Every message must have a header containing identifying and routing information. The header consists of a set of standard fields, which are defined in the Java Message Service Specification and summarized in Table 2–4. Some of these are set automatically by Message Queue in the course of producing and delivering a message, some depend on settings specified when a message producer sends a message, and others are set by the client on a message-by-message basis.
Table 2–4 Message Header Fields
Name |
Description |
---|---|
Message identifier |
|
Destination to which message is sent |
|
Destination to which to reply |
|
Link to related message |
|
Delivery mode (persistent or nonpersistent) |
|
Priority level |
|
Time of transmission |
|
Expiration time |
|
Message type |
|
Has message been delivered before? |
The JMS Message interface defines methods for setting the value of each header field: for instance,
outMsg.setJMSReplyTo(replyDest);
Table 2–5 lists all of the available header specification methods.
Table 2–5 Message Header Specification Methods
Name |
Description |
---|---|
Set message identifier |
|
Set destination |
|
Set reply destination |
|
Set correlation identifier from string |
|
Set correlation identifier from byte array |
|
Set delivery mode |
|
Set priority level |
|
Set time stamp |
|
Set expiration time |
|
Set message type |
|
Set redelivered flag |
The message identifier (JMSMessageID) is a string value uniquely identifying the message, assigned and set by the message broker when the message is sent. Because generating an identifier for each message adds to both the size of the message and the overhead involved in sending it, and because some client applications may not use them, the JMS interface provides a way to suppress the generation of message identifiers, using the message producer method setDisableMessageID (see Sending Messages).
The JMSDestination header field holds a Destination object representing the destination to which the message is directed, set by the message broker when the message is sent. There is also a JMSReplyTo field that you can set to specify a destination to which reply messages should be directed. Clients sending such a reply message can set its JMSCorrelationID header field to refer to the message to which they are replying. Typically this field is set to the message identifier string of the message being replied to, but client applications are free to substitute their own correlation conventions instead, using either the setJMSCorrelationID method (if the field value is a string) or the more general setJMSCorrelationIDAsBytes (if it is not).
The delivery mode (JMSDeliveryMode) specifies whether the message broker should log the message to stable storage. There are two possible values, PERSISTENT and NON_PERSISTENT, both defined as static constants of the JMS interface DeliveryMode: for example,
outMsg.setJMSDeliveryMode(DeliveryMode.NON_PERSISTENT);
The default delivery mode is PERSISTENT, represented by the static constant Message.DEFAULT_DELIVERY_MODE.
The choice of delivery mode represents a tradeoff between performance and reliability:
In persistent mode, the broker logs the message to stable storage, ensuring that it will not be lost in transit in the event of transmission failure; the message is guaranteed to be delivered exactly once.
In nonpersistent mode, the message is not logged to stable storage; it will be delivered at most once, but may be lost in case of failure and not delivered at all. This mode does, however, improve performance by reducing the broker’s message-handling overhead. It may thus be appropriate for applications in which performance is at a premium and reliability is not.
The message’s priority level (JMSPriority) is expressed as an integer from 0 (lowest) to 9 (highest). Priorities from 0 to 4 are considered gradations of normal priority, those from 5 to 9 of expedited priority. The default priority level is 4, represented by the static constant Message.DEFAULT_PRIORITY.
The Message Queue client runtime sets the JMSTimestamp header field to the time it delivers the message to the broker, expressed as a long integer in standard Java format (milliseconds since midnight, January 1, 1970 UTC). The message’s lifetime, specified when the message is sent, is added to this value and the result is stored in the JMSExpiration header field. (The default lifetime value of 0, represented by the static constant Message.DEFAULT_TIME_TO_LIVE, denotes an unlimited lifetime. In this case, the expiration time is also set to 0 to indicate that the message never expires.) As with the message identifier, client applications that do not use a message’s time stamp can improve performance by suppressing its generation with the message producer method setDisableMessageTimestamp (see Sending Messages).
The header field JMSType can contain an optional message type identifier string supplied by the client when the message is sent. This field is intended for use with other JMS providers; Message Queue clients can simply ignore it.
When a message already delivered must be delivered again because of a failure, the broker indicates this by setting the JMSRedelivered flag in the message header to true. This can happen, for instance, when a session is recovered or a transaction is rolled back. The receiving client can check this flag to avoid duplicate processing of the same message (such as when the message has already been successfully received but the client’s acknowledgment was missed by the broker).
See the Java Message Service Specification for a more detailed discussion of all message header fields.