Question

I am using HornetQ in distributed transaction environment with MDBs. I read from the JMS documentation that we should not create Connection instance frequently, rather we should reuse the connection and create JMS sessions as and when required. So I wrote a code which creates JMS connection and then reuse it. But I have encountered the following exception while reusing the JMS connection object.

Could not create a session: Only allowed one session per connection. See the J2EE spec, e.g. J2EE1.4 Section 6.6

I read few blogs on this but they all are specific to seam framework.

Here is my code

public class DefaultService implements IMessageService {
  private static final long serialVersionUID = 1L;
  private static final Logger logger = LogManager.getLogger(DefaultService.class);
  private static final String connectionFactoryJndiName = "java:/JmsXA";
  private static volatile Connection connection = null;
  private Session session = null;

  @Override
  public void sendMessage(String destinationStr, Serializable object) {
      try {

          Destination destination = jmsServiceLocator.getDestination(destinationStr);
          ObjectMessage message = session.createObjectMessage();
          message.setObject(object);
          MessageProducer messageProducer = session.createProducer(destination);
          messageProducer.send(destination, message);
          messageProducer.close();
          logger.trace("Sent JMS Messagae for: " + object.getClass().getName());
      }
      catch (NamingException e) {
          throw new RuntimeException("Couldn't send jms message", e);
      }
      catch (JMSException e) {
          throw new RuntimeException("Couldn't send jms message", e);
      }
  }

  @Override
  public void close() {
      try {
          if (session != null) {
              session.close();
          }
      }
      catch (Exception e) {
          logger.error("Couldn't close session", e);
      }        
  }


}

I am using JBoss EAP 6.

Did I miss any settings here?

Was it helpful?

Solution

On JCA connection (i.e. connection where you used the PooledConnectionFactory) you are supposed to create one Session only per connection. That is part of the EE specification. (It has always been).

This is because these connections are pooled and it would be impossible to put them back on the pool if you were using more than one session per connection.

If you switch for non pooled connection factories (the ones that are meant for remote clients) you would have it working the way you wanted but then you would miss pooling from the application server. EE components are usually short lived and opening / closing JMS Connections (any connection to be more precise) it's an expensive operation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top