You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by Mike Pilone <MP...@npr.org> on 2013/07/26 21:09:39 UTC

Bug in JMS Request/Reply with CACHE_NONE and Temporary Queues

I believe I found a bug in the JMS request/reply implementation if the
replyToCacheLevelName is set to CACHE_NONE in the JmsConfiguration. The
issue is that with CACHE_NONE, the DefaultMessageListenerContainer
superclass AbstractPollingMessageListenerContainer is responsible for
creating and closing a connection on each call to doReceiveAndExecute
(around line 287). 

Internal to the method, a new connection and session are created and the
createListenerConsumer is called to resolve the destination and create the
consumer. The bug is in the Camel TemporaryReplyQueueDestinationResolver
(in TemporaryQueueReplyManager (around line 201) where the temporary queue
is only refreshed if it is null or a refresh is requested (I.e. An
exception was previously raised). Because the connection is not cached,
each call to resolveDestinationName will have a new session and a new
connection but the same queue is returned.

This causes an issue with ActiveMQ because temporary queues are per
connection, therefore they can't be shared across multiple connections as
the destination resolver is attempting to do. This results in the endless
exception:

""
[WARNING] Exception inside the DMLC for Temporary ReplyTo Queue for
destination episodes.retrieve.request, refreshing ReplyTo destination
javax.jms.InvalidDestinationException: Cannot use a Temporary destination
from another Connection
""

I don't think there is a quick fix here because of the way the reply
managers work, but the current implementation only works if:
1) connection or greater caching is allowed in the DMLC
or
2) use a SingleConnectionFactory from Spring to ensure that the same
connection is used for all requests from the DMLC so essentially you are
caching the connection in the factory.

With a real connection pool implementation and DMLC CACHE_NONE, you'll get
random results depending on if the pool returns the same connection that
was used the first time the temporary reply destination was resolved. If a
different connection is returned, you'll get the exception.

You can reproduce this with a request/reply endpoint, replyToCacheName set
to CACHE_NONE, and using ActiveMQConnectionFactory directly (that is, no
pooling or SingleConnectionFactory wrapper).

Please let me know if this should be filed as a defect or if more
information is needed.

-mike


 |Mike Pilone | Software Architect, Distribution | mpilone@npr.org



Re: Bug in JMS Request/Reply with CACHE_NONE and Temporary Queues

Posted by Mike Pilone <MP...@npr.org>.
Thanks for the confirmation. It should probably clearly noted in the request/reply documentation as it is a pretty easy way to get yourself into a completely unusable configuration.

-mike

[cid:E1349351-5850-49F3-9008-CF9129E02D3C] | Mike Pilone | Software Architect, Distribution | mpilone@npr.org<ma...@npr.org> | o: 202-513-2679  m: 703-969-7493

From: Claus Ibsen <cl...@gmail.com>>
Reply-To: "users@camel.apache.org<ma...@camel.apache.org>" <us...@camel.apache.org>>
Date: Sunday, July 28, 2013 2:53 AM
To: "users@camel.apache.org<ma...@camel.apache.org>" <us...@camel.apache.org>>
Subject: Re: Bug in JMS Request/Reply with CACHE_NONE and Temporary Queues

Hi

Logged a ticket to add validation to camel-jms to not allow CACHE_NONE
for temp queues
https://issues.apache.org/jira/browse/CAMEL-6580

On Sun, Jul 28, 2013 at 8:32 AM, Claus Ibsen <cl...@gmail.com>> wrote:
Yes dont use non cache for temporary queues as they are temporary and
only associated with the session.

On Fri, Jul 26, 2013 at 9:09 PM, Mike Pilone <MP...@npr.org>> wrote:
I believe I found a bug in the JMS request/reply implementation if the
replyToCacheLevelName is set to CACHE_NONE in the JmsConfiguration. The
issue is that with CACHE_NONE, the DefaultMessageListenerContainer
superclass AbstractPollingMessageListenerContainer is responsible for
creating and closing a connection on each call to doReceiveAndExecute
(around line 287).

Internal to the method, a new connection and session are created and the
createListenerConsumer is called to resolve the destination and create the
consumer. The bug is in the Camel TemporaryReplyQueueDestinationResolver
(in TemporaryQueueReplyManager (around line 201) where the temporary queue
is only refreshed if it is null or a refresh is requested (I.e. An
exception was previously raised). Because the connection is not cached,
each call to resolveDestinationName will have a new session and a new
connection but the same queue is returned.

This causes an issue with ActiveMQ because temporary queues are per
connection, therefore they can't be shared across multiple connections as
the destination resolver is attempting to do. This results in the endless
exception:

""
[WARNING] Exception inside the DMLC for Temporary ReplyTo Queue for
destination episodes.retrieve.request, refreshing ReplyTo destination
javax.jms.InvalidDestinationException: Cannot use a Temporary destination
from another Connection
""

I don't think there is a quick fix here because of the way the reply
managers work, but the current implementation only works if:
1) connection or greater caching is allowed in the DMLC
or
2) use a SingleConnectionFactory from Spring to ensure that the same
connection is used for all requests from the DMLC so essentially you are
caching the connection in the factory.

With a real connection pool implementation and DMLC CACHE_NONE, you'll get
random results depending on if the pool returns the same connection that
was used the first time the temporary reply destination was resolved. If a
different connection is returned, you'll get the exception.

You can reproduce this with a request/reply endpoint, replyToCacheName set
to CACHE_NONE, and using ActiveMQConnectionFactory directly (that is, no
pooling or SingleConnectionFactory wrapper).

Please let me know if this should be filed as a defect or if more
information is needed.

-mike


  |Mike Pilone | Software Architect, Distribution | mpilone@npr.org<ma...@npr.org>





--
Claus Ibsen
-----------------
Red Hat, Inc.
Email: cibsen@redhat.com<ma...@redhat.com>
Twitter: davsclaus
Blog: http://davsclaus.com
Author of Camel in Action: http://www.manning.com/ibsen



--
Claus Ibsen
-----------------
Red Hat, Inc.
Email: cibsen@redhat.com<ma...@redhat.com>
Twitter: davsclaus
Blog: http://davsclaus.com
Author of Camel in Action: http://www.manning.com/ibsen



Re: Bug in JMS Request/Reply with CACHE_NONE and Temporary Queues

Posted by Claus Ibsen <cl...@gmail.com>.
Hi

Logged a ticket to add validation to camel-jms to not allow CACHE_NONE
for temp queues
https://issues.apache.org/jira/browse/CAMEL-6580

On Sun, Jul 28, 2013 at 8:32 AM, Claus Ibsen <cl...@gmail.com> wrote:
> Yes dont use non cache for temporary queues as they are temporary and
> only associated with the session.
>
> On Fri, Jul 26, 2013 at 9:09 PM, Mike Pilone <MP...@npr.org> wrote:
>> I believe I found a bug in the JMS request/reply implementation if the
>> replyToCacheLevelName is set to CACHE_NONE in the JmsConfiguration. The
>> issue is that with CACHE_NONE, the DefaultMessageListenerContainer
>> superclass AbstractPollingMessageListenerContainer is responsible for
>> creating and closing a connection on each call to doReceiveAndExecute
>> (around line 287).
>>
>> Internal to the method, a new connection and session are created and the
>> createListenerConsumer is called to resolve the destination and create the
>> consumer. The bug is in the Camel TemporaryReplyQueueDestinationResolver
>> (in TemporaryQueueReplyManager (around line 201) where the temporary queue
>> is only refreshed if it is null or a refresh is requested (I.e. An
>> exception was previously raised). Because the connection is not cached,
>> each call to resolveDestinationName will have a new session and a new
>> connection but the same queue is returned.
>>
>> This causes an issue with ActiveMQ because temporary queues are per
>> connection, therefore they can't be shared across multiple connections as
>> the destination resolver is attempting to do. This results in the endless
>> exception:
>>
>> ""
>> [WARNING] Exception inside the DMLC for Temporary ReplyTo Queue for
>> destination episodes.retrieve.request, refreshing ReplyTo destination
>> javax.jms.InvalidDestinationException: Cannot use a Temporary destination
>> from another Connection
>> ""
>>
>> I don't think there is a quick fix here because of the way the reply
>> managers work, but the current implementation only works if:
>> 1) connection or greater caching is allowed in the DMLC
>> or
>> 2) use a SingleConnectionFactory from Spring to ensure that the same
>> connection is used for all requests from the DMLC so essentially you are
>> caching the connection in the factory.
>>
>> With a real connection pool implementation and DMLC CACHE_NONE, you'll get
>> random results depending on if the pool returns the same connection that
>> was used the first time the temporary reply destination was resolved. If a
>> different connection is returned, you'll get the exception.
>>
>> You can reproduce this with a request/reply endpoint, replyToCacheName set
>> to CACHE_NONE, and using ActiveMQConnectionFactory directly (that is, no
>> pooling or SingleConnectionFactory wrapper).
>>
>> Please let me know if this should be filed as a defect or if more
>> information is needed.
>>
>> -mike
>>
>>
>>  |Mike Pilone | Software Architect, Distribution | mpilone@npr.org
>>
>>
>
>
>
> --
> Claus Ibsen
> -----------------
> Red Hat, Inc.
> Email: cibsen@redhat.com
> Twitter: davsclaus
> Blog: http://davsclaus.com
> Author of Camel in Action: http://www.manning.com/ibsen



-- 
Claus Ibsen
-----------------
Red Hat, Inc.
Email: cibsen@redhat.com
Twitter: davsclaus
Blog: http://davsclaus.com
Author of Camel in Action: http://www.manning.com/ibsen

Re: Bug in JMS Request/Reply with CACHE_NONE and Temporary Queues

Posted by Claus Ibsen <cl...@gmail.com>.
Yes dont use non cache for temporary queues as they are temporary and
only associated with the session.

On Fri, Jul 26, 2013 at 9:09 PM, Mike Pilone <MP...@npr.org> wrote:
> I believe I found a bug in the JMS request/reply implementation if the
> replyToCacheLevelName is set to CACHE_NONE in the JmsConfiguration. The
> issue is that with CACHE_NONE, the DefaultMessageListenerContainer
> superclass AbstractPollingMessageListenerContainer is responsible for
> creating and closing a connection on each call to doReceiveAndExecute
> (around line 287).
>
> Internal to the method, a new connection and session are created and the
> createListenerConsumer is called to resolve the destination and create the
> consumer. The bug is in the Camel TemporaryReplyQueueDestinationResolver
> (in TemporaryQueueReplyManager (around line 201) where the temporary queue
> is only refreshed if it is null or a refresh is requested (I.e. An
> exception was previously raised). Because the connection is not cached,
> each call to resolveDestinationName will have a new session and a new
> connection but the same queue is returned.
>
> This causes an issue with ActiveMQ because temporary queues are per
> connection, therefore they can't be shared across multiple connections as
> the destination resolver is attempting to do. This results in the endless
> exception:
>
> ""
> [WARNING] Exception inside the DMLC for Temporary ReplyTo Queue for
> destination episodes.retrieve.request, refreshing ReplyTo destination
> javax.jms.InvalidDestinationException: Cannot use a Temporary destination
> from another Connection
> ""
>
> I don't think there is a quick fix here because of the way the reply
> managers work, but the current implementation only works if:
> 1) connection or greater caching is allowed in the DMLC
> or
> 2) use a SingleConnectionFactory from Spring to ensure that the same
> connection is used for all requests from the DMLC so essentially you are
> caching the connection in the factory.
>
> With a real connection pool implementation and DMLC CACHE_NONE, you'll get
> random results depending on if the pool returns the same connection that
> was used the first time the temporary reply destination was resolved. If a
> different connection is returned, you'll get the exception.
>
> You can reproduce this with a request/reply endpoint, replyToCacheName set
> to CACHE_NONE, and using ActiveMQConnectionFactory directly (that is, no
> pooling or SingleConnectionFactory wrapper).
>
> Please let me know if this should be filed as a defect or if more
> information is needed.
>
> -mike
>
>
>  |Mike Pilone | Software Architect, Distribution | mpilone@npr.org
>
>



-- 
Claus Ibsen
-----------------
Red Hat, Inc.
Email: cibsen@redhat.com
Twitter: davsclaus
Blog: http://davsclaus.com
Author of Camel in Action: http://www.manning.com/ibsen