Category Archives: Java EE

Message Acknowledgement or Transacted Session?

JMS is one of the oldest Java EE specifications (JMS 1.0 specification is dated 11/1999), however, questions about the difference between message acknowledgement and transacted session still come up. The difference is especially subtle when programmatic client acknowledgement (Session.CLIENT_ACKNOWLEDGE) is used since Message.acknowledge() and Session.recover() are similar to Session.commit() and Session.rollback(). So how are these APIs different?

The bottom line is that there is no difference if you deal only with a single resource (Queue or Topic) within a session. If all you do is consuming messages from a single queue, it does not matter whether you use acknowledgements or transacted sessions (although in my opinion it is more intuitive to use Session.commit/rollback). Session.commit() invokes Message.acknowledge() under the covers and Session.rollback() invokes recover().

However, if you’re dealing with multiple JMS resources withing the same session (or multiple consumers/producers), the transacted session mechanism is what you want to use. For example, you may consume messages from one queue and then put messages on a different queue using the same JMS session. The transacted session will treat all consumed and produced messages as part of a single transaction and will commit or rollback all messages at once. Message acknowledgement on a non-transacted session will “commit” consumed messages independently of the produced ones.

Transacted sessions are limited to JMS resources; container-managed transactions and JTA is required to managed JMS and non-JMS resources (e.g., getting a message from a queue and updating a database).

As a summary, the different mechanisms discussed here differ in terms of the types of resources managed as part of transactions:

* Message acknowledgement: messages consumed from a single destination.
* Transacted session: multiple JMS resources within the same JMS session.
* Container-managed transactions: multiple JMS and non-JMS resources.

For a more in-depth discussion of different transaction mechanisms, refer to this article.

Note: We offer professional services in the area of WebSphere architecture, implementation and operations. If you’re looking for help with any of these tasks, please let us know.

Tips for Developing JMS Client for WebSphere Application Server

Following are some tips for developing a JMS client for WAS.

* First, we need to put the right jar files on the client’s classpath. Following jars are required: com.ibm.ws.sib.client.thin.jms_<WAS version>.jar, com.ibm.ws.ejb.thinclient_<WAS version>.jar. If you’re using Oracle/Sun JDK, you’ll also need com.ibm.ws.orb_<WAS version>.jar as IBM libraries rely on IBM ORB implementation. IBM JDK has it built-in but Oracle’s obviously does not. These jars are available from the “runtimes” directory of your WAS installation. It is a good idea to make sure that the version of your client jars matches the version of your target WAS installation, including the fixpack level. You may want to update your client jars every time a new fixpack is installed.

* If you’re not using DNS, you’ll need to add the host name of the WAS server to the host file on your client machine, otherwise you’re bound to get a cryptic ORB error message. You can find WAS host name by going to Server/Server types/ WebSphere Application Servers in admin console.
By the way, most ORB error messages are cryptic; it is very rare to see the root cause of the problem in the message. The way to deal with it is to enable ORB tracing. Add -Dcom.ibm.CORBA.Debug=true to your JDK parameters; other debug/tracing parameters are explained here.

* Another frequent source of errors is a missing bootstrap property in the connection factory configuration. It is specified in the “provider endpoint” field and has a form of <host>:<SIB_Port>:BootstrapBasicMessaging. If this is not provided, WAS will attempt to bootstrap the messaging engine using localhost.

* Most JMS examples use JNDI lookup in order to get a queue object. It is more efficient to use session.crerateQueue() method. Note that in this case you need to provide the name of the JMS destination as opposed to the queue JNDI name. This is the “Queue name” parameter on the queue configuration screen in WAS admin console.

* Finally, not all developers are aware that WAS admin console has a built-in JMS queue/topic browser. It takes a few steps to get to it from the console: Buses/Your bus name/Destinations/Your destination/Queue points/Your queue point/Runtime/Messages.

Note: We offer professional services in the area of WebSphere architecture, implementation and operations. If you’re looking for help with any of these tasks, please let us know.