Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ


Choose your language

InfoQ Homepage News What's New in JMS 2.0?

What's New in JMS 2.0?

This item in japanese

Lire ce contenu en français

Well the long awaited Java EE 7 is finally here, and with it comes JMS 2.0, the first upgrade to JMS in over a decade.

Most notable in the modern JMS specification is the willowy expressiveness of what Oracle calls the "Simplified" API. For example the new API for sending and receiving messages eliminates most of the boilerplate and dramatically reduces the amount of code required. If you're running in an application server the new API supports resource injection, allowing the application server to manage the JMS objects, which further simplifies the application.

The framework is completely backward compatible, so you are free to continue using your legacy code while implementing the Simplified API for your new code. There are no plans to deprecate the old API.

JMS 2.0 is part of the Java EE 7 platform but can also be used as a standalone Java SE platform, although not all features are available in both modes.

Let's compare some code samples using the old and new APIs.

Listing 1. JMS 1.0 Syntax for Sending a Message

1 public void sendMessage(ConnectionFactory factory,
                Queue queue, String message) { 
2    try { 
3      Connection connection = 
4      try { 
5        Session session = connection.createSession(
                false, Session.AUTO_ACKNOWLEDGE); 
6        MessageProducer messageProducer 
                 = session.createProducer(queue); 
7        TextMessage textMessage 
                 = session.createTextMessage(message); 
9        messageProducer.send(textMessage); 
11     } finally { 
12       connection.close(); 
13     } 
14   } catch (JMSException e) { 
15     // handle exception 
16   } 
17 }

Listing 2. JMS 2.0 Syntax for Sending the same Message

18 public void sendMessage(ConnectionFactory factory,
			 Queue queue, String message) { 
19   try (JMSContext context 
		= factory.createContext()) { 
21     context.createProducer().send(queue, message); 
23   } catch (JMSRuntimeException e) { 
24     // handle exception 
25   } 
26 } 

Let's analyze the changes. First up is the use of Java 7 "try-with-resources", in line 19. The new AutoCloseable JMSContext replaces both the old Connection class and Session class. When included in a try clause (line 19) all of the original "try" setup code (lines 4,11,12,13) is obviated. The message creation is also now implicit, so the resulting code is obviously a greatly trimmed down version of the original.

Also the old checked JMSException has now been replaced with the unchecked JMSRuntimeException, so it no longer needs to be explicitly caught.

That is the message sender code. The message receiver code is similarly terse.

The Simplified API is just one part of the new JMS 2.0 API. In addition there are several new semantic enhancements. There is now support for features such as:

  • Asynchronous send mode - In contrast to the traditional synchronous mode that blocks until an acknowledgement is received from the server, asynchronous mode  returns immediately without blocking. Once the acknowledgement is received, an asynchronous callback is invoked. Asynchronous mode is supported on both the new JMSProducer and its legacy counterpart MessageProducer. For example, your application can define a CompletionListener with the following interface:
public interface CompletionListener {
  void onCompletion(Message message);
  void onException(Message message, Exception exception);

Then when sending the message, you call  

  • Delayed message delivery - Allows a JMS client to schedule the future delivery of a message providing support for deferred processing, such as at the end of day. The application can set the minimum time in milliseconds that a message should be retained by the messaging system before delivery to a consumer.

    The API is similar for MessageProducer and JMSProducer:

    For MessageProducer:
    public void setDeliveryDelay(long deliveryDelay)
    For JMSProducer:
    public JMSProducer setDeliveryDelay(long deliveryDelay)
  • Sharing of the same topic subscription allows scalable consumption of messages from a topic subscription.
    New methods are provided for non-durable subscriptions.
    MessageConsumer messageConsumer = session.
    The existing method is used for durable subscriptions
    MessageConsumer messageConsumer = session.

These are just a few of the many new features. You can find a detailed tutorial providing code samples of all of the new features in the OTN article "What's New in JMS 2.0"

Rate this Article