Monday, January 13, 2014

JMS - Message Structure Overview

The main goal of a JMS application is to produce and consume messages that can then be used by other software applications. This post details the basic structure of a JMS message which consists out of three parts: headers, properties and body. For a complete overview please check the Java Message Service Concepts chapter of The Java EE 6 Tutorial.


The JMS API defines the standard form of a JMS message, which should be portable across all JMS providers. The picture below illustrates the high level structure of a JMS message.
jms message structure

JMS Message Headers

The JMS message header part, contains a number of predefined fields that must be present in every JMS message. Most of the values in the header are set by the JMS provider (which overrides any client-set values) when the message is put on a JMS destination. The values are used by both clients and providers to identify and route messages. The table below lists the JMS message header fields, indicates how their values are set and describes the content of each header field.

Header FieldSet ByDescription
JMSDestinationsend or publish methodReturns a Destination object (a Topic or a Queue, or their temporary version) describing where the message was directed.
JMSDeliveryModesend or publish methodCan be DeliveryMode.NON_PERSISTENT or DeliveryMode.PERSISTENT; only persistent messages guarantee delivery in case of a crash of the brokers that transport it.
JMSExpirationsend or publish methodReturns a timestamp indicating the expiration time of the message; it can be 0 on a message without a defined expiration.
JMSPrioritysend or publish methodReturns a 0-9 integer value (higher is better) defining the priority for delivery. It is only a best-effort value.
JMSMessageIDsend or publish methodContains a generated ID for identifying a message, unique at least for the current broker. All generated IDs start with the prefix 'ID:', but you can override it with the corresponding setter.
JMSTimestampsend or publish methodReturns a long indicating the time of sending.
JMSCorrelationIDClientCan link a message with another, usually one that has been sent previously (typically used for a request/response scenario). For example, a reply can carry the ID of the original request message.
JMSReplyToClientIs a Destination object where replies should be sent, it can be null.
JMSTypeClientDefines a field for provider-specific or application-specific message types.
JMSRedeliveredJMS providerReturns a boolean indicating if the message is being delivered again after a delivery which was not acknowledge.

JMS Message Properties

You can create and set properties for JMS messages if you need values in addition to those provided by the header fields. Properties are optional and stored as standard Java name/value pairs. Property fields are most often used for message selection and filtering.

There are three kinds of message properties:
  1. Application-related properties: A Java application can assign application-related properties, which are set before the message is delivered.
  2. Provider-related properties: Every JMS provider can define proprietary properties that can be set either by the client or automatically by the provider. Provider-related properties are prefixed with 'JMS_' followed by the vendor name and the specific property name; for example: JMS_IBM_MsgType or JMS_SonicMQ_XQ.isMultipart
  3. Standard properties: These standardized properties are set by the JMS provider (if supported) when a message is sent. Standard property names start with 'JMSX'; for example: JMSXUserid or JMSXDeliveryCount.

JMS Message Body

The message body contains the main information that is being exchanged by the JMS message. The JMS API defines five message body formats, also called message types, which allow you to send and receive data in a number of forms. JMS specifies only the interface and does not specify the implementation. This approach allows for vendor-specific implementation and transportation of messages while using a common interface.

Message TypeBody Contains
TextMessageA java.lang.String object (for example, the contents of an XML file).
MapMessageA set of name-value pairs, with names as String objects and values as primitive types in the Java programming language. The entries can be accessed sequentially by enumerator or randomly by name. The order of the entries is undefined.
BytesMessageA stream of uninterpreted bytes. This message type is for literally encoding a body to match an existing message format.
StreamMessageA stream of primitive values in the Java programming language, filled and read sequentially.
ObjectMessageA Serializable object in the Java programming language.
Some JMS vendor implementations have added additional non-standard messages types; for example SonicMQ provides a MultipartMessage message type.
The JMS API provides methods for creating messages of each type and for filling in their contents. For example, to create and send a TextMessage, you might use the following statements:
TextMessage message = session.createTextMessage();
message.setText(msg_text); // msg_text is a String
producer.send(message);

At the consuming end, a message arrives as a generic Message object and must be cast to the appropriate message type. You can use one or more getter methods to extract the message contents. The following code fragment uses the getText() method:
Message m = consumer.receive();
if (m instanceof TextMessage) {
TextMessage message = (TextMessage) m;
System.out.println("Reading message: " + message.getText());
} else {
// Handle error
}


This concludes the overview of the JMS message structure. If you found this post helpful or have any questions or remarks, please leave a comment.

No comments:

Post a Comment