Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CachingConnectionFactory doesn't properly cache producers with JMS 2.0 [SPR-11949] #16566

Closed
spring-projects-issues opened this issue Jul 3, 2014 · 5 comments
Assignees
Labels
type: bug
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

@spring-projects-issues spring-projects-issues commented Jul 3, 2014

Christopher Shannon opened SPR-11949 and commented

We just upgraded to Spring 4 and JMS 2.0. We are using a CachingConnectionFactory and a JmsTemplate to publish messages and noticed that when publishing to a destination, the first attempt works and then further attempts to publish to the same destination cause the following exception:

Caused by: javax.jms.IllegalStateException: The producer is closed

Everything worked fine with Spring 3.2 and JMS 1.1 so I did some digging to see what the problem was and it seems the issue is in the CachedMessageProducer class. Normally this class re-implements all of the methods in the MessageProducer interface. Specifically there is a close() method that is re-implemented and will only reset properties but keep the producer alive (since it is a caching factory) after a message is sent using the JmsTemplate.

However, there is a new method in Spring 4 called getProxyIfNecessary that determines whether or not JMS 2.0 is being used and when it detects JMS 2.0 it creates a Jms2MessageProducerInvocationHandler proxy. The invoke method of this proxy is delegating all calls to the original MessageProducer object, and seems to be bypassing method calls in the CachedMessageProducer. The end result is that the close method gets called on the original MessageProducer object (which we don't want since it should be cached). This means that future attempts to publish give the exception that the producer has been closed.


Affects: 4.0.5

Reference URL: http://stackoverflow.com/questions/24501329/spring-4-cachingconnectionfactory-with-jms-2-0-doesnt-properly-cache-producers

Issue Links:

  • #16567 CachedMessageProducer does not support all JMS 2.0 MessageProducer methods
  • #16572 CachingConnectionFactory doesn't properly cache all consumers with JMS 2.0
@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Jul 3, 2014

Juergen Hoeller commented

Ouch, this is a painful oversight: Jms2MessageProducerInvocationHandler needs to delegate to CachedMessageProducer.this, not to target...

Fixed for 4.1 RC1 and 4.0.6 now. Would be great if you could give the upcoming 4.0.6.BUILD-SNAPSHOT a try...

Juergen

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Jul 3, 2014

Juergen Hoeller commented

Out of curiosity, which JMS provider are you using? After all, there aren't many JMS 2.0 compliant ones around yet...

Juergen

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Jul 3, 2014

Christopher Shannon commented

Thanks for the quick response. And yes, it seemed like it was as simple as switching the target. We did a quick fix doing exactly that in our code base until this was fixed.

We use a couple of different brokers but the one our team tried JMS 2.0 with was Tibco EMS. Unfortunately, EMS requires a license so it wouldn't be suitable to test against.

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Jul 3, 2014

Christopher Shannon commented

One more thing I forgot to mention...

It appears that CachedMessageProducer's Jms2MessageProducerInvocationHandler only handles 2 out of the 4 new methods in the new JMS 2.0 MessageProducer interface that contain CompletionListener .

It handles:
send(Message message, CompletionListener completionListener)
send(Destination destination, Message message, CompletionListener completionListener)

but it doesn't seem to handle these methods:
send(Message message, int deliveryMode, int priority, long timeToLive, CompletionListener completionListener)
send(Destination destination, Message message, int deliveryMode, int priority, long timeToLive, CompletionListener completionListener)

I haven't tested this yet to confirm but it seems like this wouldn't work right since the proxy only delegates the first 2 methods correctly..... I can try and test this out next week when I get a chance.

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Jul 3, 2014

Christopher Shannon commented

I went ahead and mocked out some tests and it failed when I tried to call the methods above. I created a new Jira issue: #16567

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug
Projects
None yet
Development

No branches or pull requests

2 participants