Not so long ago, on June 12, 2013, the
release of Java EE 7 was presented to the world. One of the key points in this release was the appearance of JMS version 2.0, which has not been updated since 2002.
This text is a free translation of the beginning of the
article by Nigel Dikin . The text is intended to familiarize the interested reader with the new API.
The JMS 1.1 API requires a lot of code to work, but has managed to recommend itself well, because it has not changed since 2002. In JMS 2.0, the new API is designed to simplify the sending and receiving of JMS messages. The previous API is not abolished and continues to work on a par with the new one.
')
The JMS 2.0 API has new interfaces: JMSContext, JMSProducer and JMSConsumer.
- JMSContext replaces Connection and Session in the classic JMS API
- JMSProducer is a lightweight replacement of MessageProducer, which allows you to set message delivery settings, headers, properties, by calling the chain of methods ( Builder pattern )
- JMSConsumer replaces MessageConsumer and is used on the same principle.
Sending JMS
For comparison. JMS 1.1:
public void sendMessageJMS11(ConnectionFactory connectionFactory, Queue queue, String text) { try { Connection connection = connectionFactory.createConnection(); try { Session session =connection.createSession(false,Session.AUTO_ACKNOWLEDGE); MessageProducer messageProducer = session.createProducer(queue); TextMessage textMessage = session.createTextMessage(text); messageProducer.send(textMessage); } finally { connection.close(); } } catch (JMSException ex) {
JMS 2.0:
public void sendMessageJMS20(ConnectionFactory connectionFactory, Queue queue, String text) { try (JMSContext context = connectionFactory.createContext();){ context.createProducer().send(queue, text); } catch (JMSRuntimeException ex) {
- In version 2.0, we use try-with-resources from JavaSE 7
- The Session.AUTO_ACKNOWLEDGE parameter is set by default in the JMSContext. If you want to set a different value (CLIENT_ACKNOWLEDGE or DUPS_OK_ACKNOWLEDGE), it is passed as a separate parameter.
- JMSContext is used instead of Connection and Session objects.
- To create a TextMessage, simply pass a string to the send method.
A distinctive feature of the new API is that its methods throw a RuntimeException - JMSRuntimeException, instead of the JMSException checked-exception. This makes it possible, if desired, not to handle JMS exceptions.
JMS Sync Receive
Compare the difference when receiving messages synchronously.
JMS 1.1:
public String receiveMessageJMS11(ConnectionFactory connectionFactory,Queue queue){ String body=null; try { Connection connection = connectionFactory.createConnection(); try { Session session =connection.createSession(false,Session.AUTO_ACKNOWLEDGE); MessageConsumer messageConsumer = session.createConsumer(queue); connection.start(); TextMessage textMessage = (TextMessage)messageConsumer.receive(); body = textMessage.getText(); } finally { connection.close(); } } catch (JMSException ex) {
JMS 2.0:
public String receiveMessageJMS20(ConnectionFactory connectionFactory,Queue queue){ String body=null; try (JMSContext context = connectionFactory.createContext();){ JMSConsumer consumer = context.createConsumer(queue); body = consumer.receiveBody(String.class); } catch (JMSRuntimeException ex) {
- Use try-with-resources to automatically close a connection.
- JMSContext is used instead of Connection and Session objects.
- AUTO_ACKNOWLEDGE set as default
- Handled by JMSRuntimeException, which you can not handle, instead of JMSException in JMS 1.1
- connection.start () runs automatically
- The string is automatically obtained through the consumer.receiveBody (String.class) method, instead of receiving a Message object, casting it to TextMessage, and calling the getText method
Asynchronous JMS retrieval
In JavaSE, to receive messages asynchronously, the following code is used in JMS 1.1:
MessageConsumer messageConsumer = session.createConsumer(queue); messageConsumer.setMessageListener(messageListener); connection.start();
In JMS 2.0, it looks like this:
JMSConsumer consumer = context.createConsumer(queue); consumer.setMessageListener(messageListener);
Instead of MessageConsumer - JMSConsumer. Connection starts automatically.
In Java EE Web or EJB applications, as before, you must use the message-driven bean, instead of the setMessageListener method
Inserting a JMSContext object in a Java EE application
In a Java EE application, JMSContext can be inserted using the
Inject annotation. Once inserted, the JMSContext will be managed by the application server.
The following code snippet allows you to insert a JMSContext into a session bean or servlet.
@Inject @JMSConnectionFactory( "jms/connectionFactory") private JMSContext context; @Resource(lookup = "jms/dataQueue") private Queue dataQueue; public void sendMessageJavaEE7(String body) { context.send(dataQueue, body); }
JMSContext closes automatically by the application server. If a JTA transaction is executed during the request, the JMSContext will close automatically after the commit, if without a transaction, it will close at the end of the request.
On this I decided to stop. This information should be sufficient for familiarization and start of work. Many details and additional information here:
What's New in JMS 2.0, Part One: Ease of UseWhat's New in JMS 2.0, Part Two — New Messaging Features