I'm using Spring's JMS (v. 3.1.2) listener-container
with a JMS connectionFactory coming from WebSphere 7's JNDI settings. The application processes messages (put/get) correctly, but the backout settings set in the MQ Queue Manager don't seem to work.
To fail a message consumption, I use spring transactions with a setRollbackOnly()
, and it does increase the property "Backout count" as I can see that number increasing with the "WebSphere MQ Explorer" pointed to the remote queue.
Reading through a few IBM docs, it describes that the IBM MQ JMS client needs to move the bad message to the backout queue. Spring's listener-container
doesn't seem to be using the MQ client in a way that enables that behaviour. The backout count just keeps increasing, as if the requeue command wasn't working.
Is Spring JMS able to use that functionality? Is there anything that needs to be set in the listener-container
for it to be able to process the move to IBM MQ backout queues?
My configuration is as follows:
<tx:jta-transaction-manager/>
<jee:jndi-lookup id="connectionFactory"
jndi-name="java:comp/env/jms/myapp_queuefactory"/>
<jms:listener-container
connection-factory="connectionFactory"
transaction-manager="transactionManager">
<jms:listener destination="ONEQUEUE" ref="oneQueueListener" />
<jms:listener destination="ANOTHERQUEUE" ref="anotherQueueListener" />
<!-- many more -->
<jms:listener-container/>
The IBM MQ queue is set up with "Backout Requeue Queue" set to ONEQUEUE.BOQ
, and "Backout Threshold" to 5
.
My Spring message driven POJO java code is as follows:
@Transactional
public class MyQueueMDBean implements javax.jms.MessageListener {
public void onMessage(javax.jms.Message msg) {
try {
// some code that throws some exception ...
} catch (Exception e) {
TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
}
}
}
The Stacktrace ERROR
After the message has been rolled back 5 times, the listener starts failing to connect, as output to the logs:
[org.springframework.jms.listener.DefaultMessageListenerContainer#3-14870] WARN org.springframework.jms.listener.DefaultMessageListenerContainer - Setup of JMS message listener invoker failed for destination 'ONEQUEUE' - trying to recover. Cause: MQJMS1079: Unable to write message to dead letter queue.; nested exception is com.ibm.mq.MQException: MQJE001: Completion Code '2', Reason '2035'.
It looks like something is going on with the permission to backout the message, or the actual backout queue is not being retrieved correctly, which was unexpected since the get/puts were working OK. Still looking for an answer whether this is a valid approach though.