I've set up auto proxying and created a TransactionInterceptor to rollback on exceptions thrown from methods named "processMessage". It's configured with the following attribute:
My bean is an ActiveMQ container connector that is injected with an implementation of javax.jms.MessageListener.Code:<property name="properties"> <props> <prop key="processMessage"> PROPAGATION_REQUIRED,-MessageProcException </prop> </props> </property>
Because the MessageListener interface (method 'onMessage()') doesn't throw checked exceptions, my implementation is an abstract class that includes an abstract 'processMessage()' method that does, and that is called by onMessage(). Implementations of this class for various processing needs implement processMessage():Code:<bean id="mqConnector" ...> ... <property name="messageListener"> <ref bean="listener"/> </property> </bean> <bean id="listener" class="MyProcessor"> <property name="destination"><value>my.Queue</value></property> ... </bean>
The onMessage() method is called by the connector when a message arrives for processing. It in turn calls processMessage(). If processMessage() throws, however, the transaction is not rolled back.Code:abstract class my.MessageListenerImpl implements javax.jms.MessageListener { public void onMessage(Message m) { try { processMessage(m); } catch (Exception e) { logger.error(e.getMessage()); } public abstract void processMessage(Message m) throws MessageProcException; } class MyProcessor extends MessageListenerImpl { public void processMessage throws MessageProcException { ... } }
When I add "PROPAGATION_REQUIRED,..." for "onMessage" in the interceptor's attributes and generate unchecked exceptions in onMessage(), the transaction is rolled back, but my MQ provider (ActiveMQ) doesn't seem to handle exceptions from MessageListener implementations gracefully (although I could be misinterpreting the logs.)
I've also tried turning the two classes into two concrete classes, listener and processor, and injecting the listener with the processor but still no rollback on exception (the processor in this case still implements a processor interface). I was thinking that local method calls within a class might not execute proxy code.
I'd love advice (no pun intended) on what to try next (or whether to just throw unchecked exceptions from MessagListener) from anyone who's configured transacted JMS message processing like this -- especially with ActiveMQ.
thanks,
kirt


Reply With Quote