Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reconnecting JMS listener to JBossMQ

We have a Java listener that reads text messages off of a queue in JBossMQ. If we have to reboot JBoss, the listener will not reconnect and start reading messages again. We just get messages in the listener's log file every 2 minutes saying it can't connect. Is there something we're not setting in our code or in JBossMQ? I'm new to JMS so any help will be greatly appreciated. Thanks.

like image 273
MattGrommes Avatar asked Sep 06 '08 17:09

MattGrommes


People also ask

How do you check if JMS listener is running?

The status of the listeners is always available by running the list listeners command from the user interface or the Transaction Server console. If a listener becomes disconnected, the Transaction Server can attempt to re-connect to the queue multiple times before it fails with a connection error.

What is JMS listener concurrency?

The concurrency limits for the listener, if any. Overrides the value defined by the container factory used to create the listener container. The concurrency limits can be a "lower-upper" String — for example, "5-10" — or a simple upper limit String — for example, "10", in which case the lower limit will be 1.

What is onMessage method called in JMS?

When the queue receives a message, the EJB container invokes the message listener method or methods. For a bean that uses JMS, this is the onMessage method of the MessageListener interface.

How does JMS onMessage work?

When message delivery begins, the JMS provider automatically calls the message listener's onMessage method whenever a message is delivered. The onMessage method takes one argument of type Message , which your implementation of the method can cast to any of the other message types (see Message Bodies).


4 Answers

You should implement in your client code javax.jms.ExceptionListener. You will need a method called onException. When the client's connection is lost, you should get a JMSException, and this method will be called automatically. The only thing you have to look out for is if you are intentionally disconnecting from JBossMQ-- that will also throw an exception.

Some code might look like this:

    public void onException (JMSException jsme)
    {
        if (!closeRequested)
        {
            this.disconnect();
            this.establishConnection(connectionProps, queueName, uname, pword, clientID, messageSelector);
        }        
        else
        {
            //Client requested close so do not try to reconnect
        }
    }

In your "establishConnection" code, you would then implement a while(!initialized) construct that contains a try/catch inside of it. Until you are sure you have connected and subscribed properly, stay inside the while loop catching all JMS/Naming/etc. exceptions.

We've used this method for years with JBossMQ and it works great. We have never had a problem with our JMS clients not reconnecting after bouncing JBossMQ or losing our network connection.

like image 99
Todd Avatar answered Oct 11 '22 14:10

Todd


I'd highly recommend you use the Spring abstractions for JMS such as the MessageListenerContainer to deal with reconnection, transactions and pooling for you. You just need to supply a MessageListener and configure the MessageListenerContainer with the ConnectionFactory and the container does the rest.

like image 28
James Strachan Avatar answered Oct 11 '22 16:10

James Strachan


If you're purely a listener and do no other JMS calls other than connection setup, then the "onException() handler" answer is correct.

If you do any JMS calls in your code, just using onException() callback isn't sufficient. Problems are relayed from the JMS provider to the app either via an exception on a JMS method call or through the onException() callback. Not both.

So if you call any JMS methods from your code, you'll also want to invoke that reconnection logic if you get any exceptions on those calls.

like image 45
John M Avatar answered Oct 11 '22 16:10

John M


Piece of advice from personal experience. Upgrade to JBoss Messaging. I've seen it in production for 4 months without problems. It has fully transparent failover - amongst many other features.

Also, if you do go with Spring, be very careful with the JmsTemplate.

like image 26
user13229 Avatar answered Oct 11 '22 14:10

user13229