Sending JMS messages

An application sends a message to the JMS provider using a javax.jms.JMSProducer producer. This producer can be obtained from a JMSContext in the simplified API in JMS 2.0 by calling the createProducer() method.

Upgrading message producers from JMS 1.1

In JMS 1.1, creating a javax.jms.MessageProducer object sends the messages. Developers who are fortunate enough to experience this API will see code that looks similar to this:

// JMS 1.1
Connection conx = 
  queueConnectionFactory.createConnection();
Session session = conx.createSession(true, 
  Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = session.createProducer()
producer.setDeliverDelay(10*1000)
producer.setPriority(7)
producer.setTimeToLive(1000)
producer.setDeliverMode(DeliveryMode.NON_PERSISTENT)
producer.send(destination, message );

The older API only provides bean setter methods in order to configure destination parameters. JMSProducer is the preferred way for JMS 2.0 because it always supports the fluent-style of interface; it has method chaining:

// JMS 2.0
JMSContext context = /* Injected */
JMSProducer producer = context.createProducer()
producer.setDeliverDelay(10*1000)
  .setTimeToLive(1000)
  .setPriority(7)
  .setDeliverMode(DeliveryMode.NON_PERSISTENT)
  .send(destination, message );

The method chaining is clearer, eminently readable, and affords declarative code.

Sending messages synchronously

Synchronous sending occurs when the JMS client sends a message to the channel and the provider does not return the thread of control to the sender until it knows that the consumer endpoint has received and acknowledged that successful consumption of the message. This is an example of block-and-wait.

The JMSProducer defines these methods as synchronous operations in the simplified API:

send(Destination destination, Message message)
send(Destination destination, String body)
send(Destination destination, Map<String,Object> body)
send(Destination destination, byte[] body)
send(Destination destination, Serializable body)
send(Destination destination, String body)	

Note that there is no need to create the intermediate Message type object. Incidentally, the developer can set custom key value and pair properties on the JMSProducer instance using the method setStringProperty().

Sending messages asynchronously

A JMSProducer can also send messages asynchronously so the caller does not block-and-wait on the consumer to successfully acknowledge the message on the channel. This is a performance feature that is intended for unmanaged environment Java SE applications rather than inside an application server.

The JMSProducer defines a setAsync() method in the simplified API and it takes a single argument: an implementation of the Java interface class javax.jms.CompletionListener.

The definition of CompletionListener is as follows:

package javax.jms;
public interface CompletionListener {
  void onCompletion(Message message);
  void onException(Message message, Exception exception);
}

A completion listener must be registered prior to calling any of the send() overloaded methods on JMSPublisher. The JMS provider invokes the callback onCompletion() method when the consumer successfully consumes the message. It will invoke the callback method onException() instead when a failure occurs delivering the message to the consumer.

Note

setAsync() on a JMSProducer may not be called inside a Java EE web or EJB container. Asynchronous sending is designed for standard JMS applications running on Java SE. There is another way, and that is to write a concurrent worker, java.lang.Runnable or java.util.concurrency.Callable, that creates and sends messages on a destination object, JMSProducer. Concurrent tasks are made available in Java EE 7 Concurrency Utilities (JSR 236) through the new service ManagedExecutorService. Read more in Appendix D, Java EE 7 Assorted Topics.

JMS message headers

Every JMS message has a map collection of header fields which are name and value pairs. The message header is sent to all the JMS clients and they are able to read the complete message with the headers on the consumer side.

The names of the header fields begin with the prefix 'JMS' string; here is a table of the headers and their descriptions:

Header Field

Side

Description

JMSDestination

Provider

Contains the destination for the message.

JMSDeliverMode

Provider

Specifies the delivery mode when the message was sent.

JMSMessageID

Provider

Specifies the value that uniquely identifies each message sent by the JMS provider. The JMS provider always assigns the value and starts with the prefix 'ID:' string

JMSTimestamp

Provider

This field contains the time that the message was sent from the JMS client and accepted by the provider.

JMSCorrelationID

Provider

This field links one message with another in order to group together messages. This is a field that the client application can customize whilst sending the message. The correlation field typically associates a request message with a reply message.

JMSReplyTo

Client

Specifies a Destination supplied by a client when the message is sent. The consumer then sends the response to the target channel.

JMSRedelivered

Provider

This field informs the consumer that a message was delivered but not acknowledged in the past. It is a strong hint to check for a duplicate message with the same ID in the backend database.

JMSType

Client

Specifies the message type identifier supplied by the client.

JMSExpiration

Provider

Specifies the expiration time whenever a message producer sends a message with which the JMS provider calculates an expiration time by adding the time-to-live values on the context. The value is measured in milliseconds since midnight, 1st January, 1970.

JMSPriority

Client

Specifies the priority of the message. The value of 0 is the lowest priority and the value of 9 is the highest. The range 0-4 gradations are defined as normal priority and the range 5-9 gradations are defined as expedited in the standard.

Most of these properties are set on the javax.jms.Message type, but they can be set on the JMSProducer type directly in a fluent API style.

The standard reserves the JMSX property prefix for JMSdefined properties. These are defined as key and value pairs on the message header and are important for message consumers.

Setting message properties

An application can also set additional properties on JMS messages just before it is sent to the provider. There is a complete set of overloaded setProperty() methods for every Java primitive except char. The method setProperty( String, Object ) allows a Java primitive wrapper to be passed such as java.lang.Long. Calling setProperty with the same key and a different value overwrites the previous key-value association.

Setting a message delivery delay

In JMS 2.0, it is also possible to set a delivery delay on messages in which the case JMS provider understands that the message must be delayed on the message destination and not delivered until the delay period expires.

An application can call the method setDeliveryDelay(long) on the JMSProducer instance, which accepts a single argument: the delay period in milliseconds.

Tip

Delivery delay of bank trade messages

Why is this feature so useful? Imagine a bank that trades on the stock market in two geographic locations. One location for the bank is in London, Great Britain, and the other in New York, United States. The financial centers are only open for certain trading hours during the day. Let us say that both are open from 08:00 to 16:00. Let's also say we have a trader called Brian in London who agrees a new deal with a counterparty and then creates a new trade at exactly 09:00. This trade is dependent on a derivative data that is derived from information effective in the USA. The full execution of the trade cannot take place until the market in New York opens in four hours time at 01:00 London time because the time zone difference between London and New York is five hours (GMT -5:00). The London trading system can still post a trade message to the downstream system for further execution because it can add a special message property to delay delivery of the message for 4 hours. The downstream will only receive the trade message once the delay expires.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.12.108.175