javajmsactivemq-classicmom

Handling JMSExceptions when using JMS, specifically ActiveMQ?


In the following snippet:

Connection connection=getConnection();
try {
    Session session=connection.createSession();
    try {
        Queue queue=session.createQueue("foobar");
        MessageConsumer consumer=null;
        try {
            consumer = session.createConsumer(queue);
        }
        catch(JMSException e) {
            // Under what circumstances does this happen?
        }
        try {
            // ...
        }
        finally {
            if(consumer != null) consumer.close();
        }
    }
    finally {
        session.close();
    }
}
finally {
    connection.close();
}

Under what circumstances is the caught JMSException thrown? When it happens, what is the proper way to handle the JMSException? I've read the relevant bits of JMS and ActiveMQ documentation and it doesn't seem to give any guidance on this point (other than use try/catch, obviously.) Also please forgive the contrived code example!

For example, does a JMSException happen if session has "gone bad" in some way, so it's The Right Thing to tear down consumer and session and start over? Or does it mean connection has gone bad, and so I should tear down and rebuild everything in the application that is based on that connection? Or can a call to createConsumer() fail in a transient way, and retrying the call with the same session could succeed?

Similarly, when would these lines throw a JMSException, ignoring something like a closed Session or Connection:

Message message=consumer.receive();
producer.send(message);

I'd like to understand how JMSExceptions should be handled in JMS in general, but answers specific to ActiveMQ are fine, too. (In fact, it's likely that any answer may have to be specific to a specific implementation, since JMS is just a spec.)


Solution

  • The exceptions can be thrown for a number of reasons. The most common would be that the connection was lost due to a down network or broker. Other reasons can be resource exhaustion on the broker, security violations, etc.

    To avoid the exceptions caused by network connection issues you can use ActiveMQ's failover transport to have the client do automatic reconnection. There are a number of exception types in JMS so you can test for a given error, like checking to see if consumer creation or producer send failed because of a security exception. If you don't know the actual causes then the most common thing to do is tear down and rebuild your connection resources. This is why using failover is better as you can avoid a lot of work by letting the client handle detecting and responding to this.