Home > Enterprise >  ActiveMQ Artemis: javax.jms.IllegalStateRuntimeException: Session is closed after interruption in Po
ActiveMQ Artemis: javax.jms.IllegalStateRuntimeException: Session is closed after interruption in Po

Time:06-24

Recently we have upgraded ActiveMQ Artemis version from 1.5.3 to 2.21.0 and now using PostgreSQL to store the messages. Earlier we were storing the messages in file system.

ActiveMQ Artemis is used as a embedded server inside a Spring-based Java web application.

We are getting following error if connection to the PostgreSQL is temporarily interrupted:

javax.jms.IllegalStateRuntimeException: Session is closed
    at org.apache.activemq.artemis.jms.client.JmsExceptionUtils.convertToRuntimeException(JmsExceptionUtils.java:59)
    at org.apache.activemq.artemis.jms.client.ActiveMQJMSContext.createMapMessage(ActiveMQJMSContext.java:257)
    at com..data.core.messaging.dataload.BaseDataLoaderMessageSender.getMapMessage(BaseDataLoaderMessageSender.java:220)
    at com.test.data.core.messaging.dataload.BaseDataLoaderMessageSender.send(BaseDataLoaderMessageSender.java:140)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: javax.jms.IllegalStateException: Session is closed
    at org.apache.activemq.artemis.jms.client.ActiveMQSession.checkClosed(ActiveMQSession.java:1255)
    at org.apache.activemq.artemis.jms.client.ActiveMQSession.createMapMessage(ActiveMQSession.java:169)
    at org.apache.activemq.artemis.jms.client.ActiveMQJMSContext.createMapMessage(ActiveMQJMSContext.java:255)
    ... 132 more

The sequeunce of events are

  1. Start the server
  2. Shutdown DB
  3. Perform some action on JMS queue like send a message/read messages from queue - It will fail. This is expected
  4. Start DB
  5. Perform some action on JMS queue like send a message/read messages from queue

In the step 5 as the connection is restored then I expect it to be successful.

ConnectionFactory is created as a Spring bean:

    <bean id="queueConnectionFactory"
          >
        <constructor-arg value="false"/>
        <constructor-arg>
            <bean >
                <constructor-arg
                        value="org.apache.activemq.artemis.core.remoting.impl.invm.InVMConnectorFactory"/>
            </bean>
        </constructor-arg>
        <property name="ConsumerWindowSize" value="0"/>
    </bean>

And the JMSContext and MessageProducer are being created as

jmsContext = connectionFactory.createContext();
producer = jmsContext.createProducer();

Note: I tried to recreate ConnectionFactory programatically in case of exception but still the same issue.

Can anyone suggest what can be wrong here?

CodePudding user response:

It's hard to say what exactly be happening without more details (e.g. logging from the broker), but in general behavior you're seeing is what I would expect. When the broker is unable to perform operations on the message store (e.g. file-system, database, etc.) this is considered a "critical" error and the broker will shut itself down. Once you restore connectivity you need to restart the broker, and there's no evidence that you're doing that.

You can register a callback with your embedded broker to be alerted when certain life-cycle events occur. Use org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl#registerActivateCallback and pass it an org.apache.activemq.artemis.core.server.ActivateCallback implementation. You could probably use this callback to restart the broker automatically in case of a failure of this kind.

Generally speaking I would recommend you use the file-based journal rather than JDBC as performance will be much better and it will be more robust.

  • Related