You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by vassilis <2b...@gmail.com> on 2015/01/23 16:23:35 UTC

jms acknowledgement is not send to ActiveMQ Broker from camel jms consumer

Hi all!

Problem description:

Sometimes (in my tests usually for 6-10 jms messages out of 60) when the
camel jms consumer (configured with AUTO_ACKNOWLEDGE) consumes a message and
an Exception is thrown in a later stage of the route (e.g. by a processor
that uses this jms message body), then the ActiveMQ broker never receives
the message consumption acknowledgement (or more likely, the jms camel
consumer never sends it) for this message.

The result is that these messages stay in the queue and are not consumed
(also stay always in-flight). More specifically, if you go to Hawtio
ActiveMQ you can see that some jms consumers (I have ten configured) have
"message count waiting acknowledge" > 0. In fact, if you some these values,
the sum equals to the number of not consumed message in the queue.

I can consistent reproduce the problem. My conclusion is that this erroneous
behaviour (if it is erroneous) happens only if the thrown exception is
handled (e.g. use a dead-letter-queue error handler). If it is not handled
(e.g. use default-error-handler or use OnException().handled(false)), then
it is not reproducible!

My understanding is:

That by the time the message is consumed by the jms consumer and enters the
camel route, the consumer should have already sent the message consumption
acknowledgement to the Broker and the Broker will then delete the message
from the queue. Because I am using AUTO_ACKNOWLEDGE. So the fact that an
exception is thrown later in the route is completely irrelevant (or it
should be).

So my question is:

Have I mis-understood something? When the message is acknowledged? And why
the handling of the exception "sometimes" affects the sending of the
acknowledgement to the broker from the jms consumer?

The two routes (one that the problem is reproducible and one that is NOT)
and their ActiveMQ connection configuration will follow.

Many thx in advance!

Any help is more than welcome!

------

Here is the route that reproduces the problem:

<errorHandler id="xmlMessageDeadLetterHandler" type="DeadLetterChannel" 
deadLetterUri="{{mq.xmlMessage.queue.dlq}}" 
useOriginalMessage="true">
<redeliveryPolicy maximumRedeliveries="0" retriesExhaustedLogLevel="ERROR"
retryAttemptedLogLevel="WARN" logStackTrace="true" /> 
</errorHandler>

<bean id="forced" class="javax.mail.MessagingException">
</bean>

<route id="xmlMessageMailer" errorHandlerRef="xmlMessageDeadLetterHandler">

<from uri="jms:esb.mailer.xmlMessage?destination.consumer.prefetchSize=1" />

<log message="Step 1" />

<unmarshal>

<jaxb contextPath="com.quindell.mailer" prettyPrint="true"
partClass="com.quindell.mailer.MailMessage"
partNamespace="{http://quindell.com/mailer/}MailMessage" />

</unmarshal>

<log message="Step 2" />

<process ref="mailProcessor" />

<log message="Step 3" />

<throwException ref="forced" />

<log message="Step 4" />

</route>

-----------

Here is the "same" route that the problem is NOT reproduced:


<route id="xmlMessageMailer">

<from uri="jms:esb.mailer.xmlMessage?destination.consumer.prefetchSize=1" />

<onException>
<exception>java.lang.Exception</exception>
<redeliveryPolicy maximumRedeliveries="0"
retriesExhaustedLogLevel="ERROR" retryAttemptedLogLevel="WARN"
logStackTrace="true" />
<handled>
<constant>false</constant>
</handled>
<to uri="{{mq.xmlMessage.queue.dlq}}" />
</onException>

<log message="Step 1" />

<unmarshal>

<jaxb contextPath="com.quindell.mailer" prettyPrint="true"
partClass="com.quindell.mailer.MailMessage"
partNamespace="{http://quindell.com/mailer/}MailMessage" />
</unmarshal>

<log message="Step 2" />

<process ref="mailProcessor" />

<log message="Step 3" />

<throwException ref="forced" />

<log message="Step 4" />

</route>

-------------

For both routes I use:

	<bean id="jmsConnectionFactory"
class="org.apache.activemq.ActiveMQConnectionFactory">
		<property name="brokerURL" value="tcp://localhost:61616" />
		<property name="userName" value="${mq.user}" />
		<property name="password" value="${mq.pass}" />
	</bean>

	<bean id="pooledConnectionFactory"
class="org.apache.activemq.pool.PooledConnectionFactory"
		init-method="start" destroy-method="stop">
		<property name="maxConnections" value="8" />
		<property name="connectionFactory" ref="jmsConnectionFactory" />
	</bean>

	<bean id="jmsConfig"
class="org.apache.camel.component.jms.JmsConfiguration">
		<property name="connectionFactory" ref="pooledConnectionFactory" />
		<property name="concurrentConsumers" value="10" />
	</bean>

	<bean id="jms"
class="org.apache.activemq.camel.component.ActiveMQComponent">
		<property name="configuration" ref="jmsConfig" />
	</bean>









--
View this message in context: http://camel.465427.n5.nabble.com/jms-acknowledgement-is-not-send-to-ActiveMQ-Broker-from-camel-jms-consumer-tp5762063.html
Sent from the Camel - Users mailing list archive at Nabble.com.