1

I'm using JMS (Apache Qpid) to create connections to a message broker. I do create some connections and cache those in a Map (Map<String, Connection>). However, the message broker has its natural limits (in terms of resources like connections per user) which gets hit a some time. If I configure a connection via Qpid to use an idle timeout the connections in my map will constantly disconnect and connect again. Let's say the limit of connection is set to 3 and I create a 4th connection right in the moment when an idle timeout kicks in the 4th connection might connect and "steal" the connection. So the 4 connections will fight for the limit the message broker has. I've registered an exception listener and I do see the error occuring. I would like to close an connection on a specific error but it seems like I've no controll about that.

So how do I manage the lifecycle of a connection? Is there a way to get information about if a connection is connected or not?

monti
  • 455
  • 7
  • 25
  • Why does it seem like you have no control over closing a connection on a specific error? – Justin Bertram Nov 20 '20 at 13:45
  • When using an exception listener I don't know on which connection the exception occured as well I don't see a method on a connection which tells me if a connection is connected or not. (https://docs.oracle.com/javaee/7/api/javax/jms/Connection.html) – monti Nov 20 '20 at 13:53
  • Why don't you just add some meta-data to your `ExceptionListener` implementation so you can match it up with the `Connection` from your `Map`? You could use the same `String` that you use in your `Map`. Also, why are you creating so many connections in the first place? Typically clients would just create a single connection and multiple sessions to divide work (if necessary). – Justin Bertram Nov 20 '20 at 14:01
  • I will get the the meta information of the connection then, I agree. I could close the connection on a specific exception but that would mean parsing a string (the exception). But I don't which connection was used for consuming or sending - I guess I would need to add that to my connection as meta-data aswell. – monti Nov 20 '20 at 14:09

2 Answers2

0

I believe you should add some meta-data to your ExceptionListener implementation in order to correlate it with the relevant connection. You could potentially use the same String value which you use in your Map<String, Connection>. You could also just set the Connection directly in your ExceptionListener implementation.

Aside from that you might reconsider creating multiple connections from your client in the first place. Generally speaking, one connection per client is sufficient. If you need to logically separate different tasks (e.g. producing & consuming) then you can create multiple sessions. This would have the benefit of simplifying your client application and using fewer resources on the broker.

Lastly, the JMS API doesn't provide any direct mechanism to test a connection's validity. In general it is safe to assume the connection is valid unless you receive an exception either synchronously or asynchronously via the ExceptionListener.

Justin Bertram
  • 29,372
  • 4
  • 21
  • 43
0

I also had same problem. As JMS specification have no method to get connection status, so you can use alternative method to get status

I use getClientID() to check connection status inside exception listener. If you take a look on implementation of getClientID() operation then you can see that they are first checking connection status and then providing connection ID

protected boolean isConnectionActive() { 
        boolean connectionStatus = false; 
        try { 
            String clientID = getConnection().getClientID(); 
            connectionStatus = true; 
        } catch (Exception e) { 
            connectionStatus = false; 
        } 
        return connectionStatus; }
    

NOTE - this solution will definitely work upto latest library 0.55, but in future Qpid Team can change implementation of getClientID().

Abhishek Kumar
  • 435
  • 1
  • 6
  • 16