How to handle a Connection object to remote jms server

拜拜、爱过 提交于 2019-12-11 07:18:03

问题


We are using an application that contains a jboss @Service mbean which encapsulates a javax.jms.Connection object.

During startup of the mbean the connection is created by initializing a remote InitialContext, looking up the ConnectionFactory from that context, and creating a connection from that factory:

@Service
public class JMSPublisher extends etcc.... {
   private Connection connection;
   protected void startService() {
      Context ctx = getRemoteInitialContext();
      ConnectionFactory connectionFactory = (ConnectionFactory) ctx.lookup("ConnectionFactory");
      connection = connectionFactory.createConnection();
   }
}

My question is: how long can we be supposed to maintain that connection ? In practise we see that the connection throws a JMSException when we try to create a session on it after an undefined amount of time.

The documentation of Connection tells us that an object represents a socket, so timeouts due to inactivity could be normal. But how can we deal with it without creating new connections for each and every message ?


回答1:


Your best bet is to have JMSPublisher implement javax.jms.Exception listener. Implement a connect() method which safely acquires a connection on:

  1. startService
  2. onException

A couple of extra points:

  • For code compression, simply acquire the JMS connection factory via resource injection. The connection factory reference will be resolved before startService is called and will also act as an implicit depends, making the JMS connection factory a dependency for your service.

  • Have JMSPublisher extend org.jboss.system.ServiceMBeanSupport and implement a token MBean interface (JMSPublisherMBean) that extends org.jboss.system.ServiceMBean. This will ensure that the dependencies are honoured on service start (and stop).

Resource Injected JMS Connection Factory

@Resource(mappedName="ConnectionFactory") 
private javax.jms.ConnectionFactory connectionFactory;
private volatile javax.jms.Connection connection;

Modified startService()

public void startService() {
   connect();
}

Connection Exception Handler

public void onException(JMSException je) {
   connect();
}

*Safe Connection Initializer (adding conn.start()) *

private void synchronized connect() {
    log.info("Initializing Connection....");
    try {
        if(connection!=null) {
           try { connection.stop(); } catch (Exception e) {}
           try { connection.close(); } catch (Exception e) {}
        }
        connection = connectionFactory.createConnection();
        connection.setExceptionListener(this);
        connection.start();
    } catch (Exception e) {
        log.error("Failed to intialize JMS connection", e);
    }
}

This will not automatically take care of other JMS resources allocated through the lost connection, but if other components are using the connection held by this component, you can publish JMX Notifications from JMSPublisher indicating that the connection has been lost and clean up/re-acquire on the notification receipt.



来源:https://stackoverflow.com/questions/6545374/how-to-handle-a-connection-object-to-remote-jms-server

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!