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.
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.