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.
Has anyone else had this issue before? I'm not sure if I'm doing something wrong or if this is a bug with the new JMS 2.0 support in Spring.