Skip to main content

JMS Exception on Cluster

Please note these java.net forums are being decommissioned and use the new and improved forums at https://community.oracle.com/community/java.
6 replies [Last post]
mauriff
Offline
Joined: 2006-08-19
Points: 0

Hi all,
I'm creating a cluster that contains application with JMS.

I've create the resources:

${ASADMIN_HOME} create-jms-resource --target gfCluster --restype
javax.jms.QueueConnectionFactory --description "connection factory for
process plugin project" --property jdni_name=jms/QueueConnectionFactory
jms/QueueConnectionFactory;
${ASADMIN_HOME} create-jms-resource --target gfCluster --restype
javax.jms.Queue --property Name=PluginMetricsQueue jms/PluginMetricsQueue;

And I have this snip of code

connection = connectionFactory.createConnection();
session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);

When the session is created I got:

SEVERE: Exception occurred, reason: {}
com.sun.messaging.jms.JMSException: MQRA:CA:createSession failed-Only one
JMS Session allowed when managed connection is involved in a transaction
at
com.sun.messaging.jms.ra.ConnectionAdapter.createSession(ConnectionAdapter.java:338)

Can you help me?

Thanks in advance,
Mauricio

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
liang.x.zhao
Offline
Joined: 2011-12-18
Points: 0

Hi Mauricio,

You are welcome!

The exception is about your application is trying to create a secondary session from one connection inside a transaction, which is not allowed. Please make sure you have closed all connections and sessions properly after use.

What GF (MQ) version are you using? What is the JMS mode, EMBEDDED, LOCAL or REMOTE? Is that load related? Could you provide a complete test case for reproducing?

Thanks,
David Zhao

mauriff
Offline
Joined: 2006-08-19
Points: 0

Hi David,
I'm using GF 3.2.1. I've tried with different modes EMBEDDED and LOCAL.

The steps to reproduce are:
1.Create a cluster with two nodes and two instances
2.Create ConnectionFactory and Queue with
3.Create a Connection and leave it open
4.Try to create a session.

Find attached my JMS resources creation and a snippet of my code.

Thanks,
Mauri

nigeldeakin
Offline
Joined: 2007-10-12
Points: 0

Here's your send method:

public void send(QueueItem queueItem) {
   logger.fine("Session object is created..");
   Session session = connection.createSession(false,
   Session.AUTO_ACKNOWLEDGE);
   MessageProducer producer = session.createProducer(dest);
   logger.fine("Producer object is created..");
   ObjectMessage message = session.createObjectMessage();
   message.setObject(queueItem);
   producer.send(message);
}

This method creates a new session from the same connection. I don't see any code to close this session (or the connection) after use. This means that the second time you call this method you'll violate the Java EE restriction that says that an application running in a Java EE web or EJB container may only create one session per connection.

In general, it's best to close the connection and session after you've finished using it. Closing the connection will automatically close the session. So the following should work:

public void send(QueueItem queueItem) {
   Connection connection = connectionFactory.createConnection();
   Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
   MessageProducer producer = session.createProducer(dest);
   ObjectMessage message = session.createObjectMessage();
   message.setObject(queueItem);
   producer.send(message);
   connection.close();
}
mauriff
Offline
Joined: 2006-08-19
Points: 0

Yes, I changed the code to create and close the connection in the send method as a workaround.

But, I can not changed the code because the same legacy code works for websphere and we are trying to migrate to GF.

Thanks,
Mauricio

nigeldeakin
Offline
Joined: 2007-10-12
Points: 0

Glad you got it to work.

Note that your change is a fix, not a workaround. Your previous code was incorrect as it (1) violated the Java EE restriction that you can only have one session per connection (2) leaked sessions.

Java EE 6 specification section EE 6.7 states "Application components in the web and EJB containers must not attempt to create more than one active (not closed) Session object per connection. An attempt to use the Connection object’s createSession method when an active Session object exists for that connection should be prohibited by the container. The container should throw a JMSException if the application component violates this restriction."

mauriff
Offline
Joined: 2006-08-19
Points: 0

You right, I'm going to change the code definitively.

Thanks for your help guys!!