blueSky
blueSky

Reputation: 659

JMS commit fails

We have an application that uses JMS with Tibco messaging server. It’s implemented with Spring Boot. Our sessions are transacted sessions and the acknowledge mode is set to auto. We can receive the messages sent to the queue but for some reason that commit() method fails.

This is the error:

2018-07-13 15:50:35.858  WARN 2576 --- [enerContainer-8] o.s.j.l.DefaultMessageListenerContainer  : Execution of JMS message listener failed, and no ErrorHandler has been set.

javax.jms.TransactionRolledBackException: Commit failed

2018-07-13 15:50:35.914  WARN 2576 --- [enerContainer-8] o.s.j.l.DefaultMessageListenerContainer  : Setup of JMS message listener invoker failed for destination 'queue' - trying to recover. Cause: Commit failed; nested exception is javax.jms.JMSException: operation='ack' cause='Illegal state' queue='queue'

I should mention two things:

Does anybody have any idea that why the commit() fails? When the commit fails, the transaction is rolled back and the messages won’t be cleared from the queue.

Why I see this error only in debug mode? OR: it indeed, does happen when I run the war but just not logged?

Below please find the complete stack trace:

15:50:35.858 [DefaultMessageListenerContainer-8] WARN  o.s.j.l.DefaultMessageListenerContainer - Execution of JMS message listener failed, and no ErrorHandler has been set.
javax.jms.TransactionRolledBackException: Commit failed
    at com.tibco.tibjms.Tibjmsx.buildException(Tibjmsx.java:596)
    at com.tibco.tibjms.TibjmsxSessionImp._confirmTransacted(TibjmsxSessionImp.java:3251)
    at com.tibco.tibjms.TibjmsxSessionImp._confirm(TibjmsxSessionImp.java:3643)
    at com.tibco.tibjms.TibjmsxSessionImp._commit(TibjmsxSessionImp.java:2898)
    at com.tibco.tibjms.TibjmsxSessionImp.commit(TibjmsxSessionImp.java:4860)
    at org.springframework.jms.support.JmsUtils.commitIfNecessary(JmsUtils.java:218)
    at org.springframework.jms.listener.AbstractMessageListenerContainer.commitIfNecessary(AbstractMessageListenerContainer.java:776)
    at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:680)
    at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:318)
    at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:257)
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1189)
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1179)
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1076)
    at java.lang.Thread.run(Unknown Source)
2018-07-13 15:50:35.914  WARN 2576 --- [enerContainer-8] o.s.j.l.DefaultMessageListenerContainer  : Setup of JMS message listener invoker failed for destination 'queue' - trying to recover. Cause: Commit failed; nested exception is javax.jms.JMSException: operation='ack' cause='Illegal state' queue='queue'
2018-07-13 15:50:36.543  INFO 2576 --- [enerContainer-8] o.s.j.l.DefaultMessageListenerContainer  : Successfully refreshed JMS Connection
15:50:36.543 [DefaultMessageListenerContainer-8] INFO  o.s.j.l.DefaultMessageListenerContainer - Successfully refreshed JMS Connection

Upvotes: 1

Views: 3618

Answers (1)

Axel Podehl
Axel Podehl

Reputation: 4303

This EMS exception happens when some of your messages within that transaction expired in the meantime. Just tried this one myself.

When you run outside of debugging mode, things seem to be quick enough. But when you are in debugging mode, your time before you commit() is much longer. So if your producer's time-to-live expires in the meantime, the commit assumes that something is wrong (EMS knows that there should be e.g. 5 messages in this transaction, but one of them already expired) and throws this exception.

To verify your producer's time-to-live, see the last option of your MessageProducer.send() call or msgProducer.setTimeToLive() and note, this is a time in millseconds, not seconds. Another way to check if this is the issue, is to run in debug mode and be 'really quick' with continuing your thread. That might change your behaviour.

Upvotes: 1

Related Questions