What Is Java Message Service (JMS)

Introduction

 
JMS provides headers for every message. Fields inside the header contain extra information about the message contents. Information inside the message header is always passed from MessageProducer interface to MessageConsumer interface. Some of these fields may be set automatically by the JMS service once the message is sent to the consumer, but the MessageProducer also has the option of setting some fields.
 

Message Header

 
Some important message header fields are below,
 
JMSCorrelationID
 
This field provides a way to correlate messages in a request/response type of setup. The JMSCorrelationID filed can be a vendor-specified ID, an application-generated code, or a provider-native byte value. Onlu vendor-generated IDs may use the ID prefix. It cannot be sued in an application-generated ID code. This field is set by the send() method of the QueueSender interface or publish() method of the TopicPublisher interface.
 
JMSDestination
 
This field specifies the destination for a message. The value may be either a queue or a topic. The JMSDestination field is automatically set by the JMS provider when the send() method is called.
 
JMSExpiration
 
This field contains the validity period for the message. The message will be deleted once this period is over, irrespective of whether the message has been delivered or not. Even messages in the PERSISTENT mode are deleted once they expire. This field is set by the send() method of the QueueSender interface or the publish() method of the TopicPublisher interface.
 
JMSDeliveryMode
 
This field specifies whether the message is to be delivered in PERSISTENT or NON-PERSISTENT delivery mode. In NON-PERSISTENT mode, messages may be lost in case of a system failure. In PERSISTENT mode, the application or vendor defines whether the message will be stored in a file or in a database so that data is not lost in case of system failure. The PERSISTENT mode requires higher overhead and affects performance. You also have to configure the storage management settings, resulting in more up-front. This field is set by the send() method of the QueueSender interface or publish() method of the TopicPublisher interface.
 
JMSMessageID
 
This header field contains a unique identifier for each separate message sent by a provider. This identifier is initialized automatically by the message provider. The identifier is returned to the MessageProducer when the send() method returns but since, the message provider initializes the JMSMessageID field, this value is not unique across multiple message providers. A value may be assigned to two different messages by different message providers. JMSMessageID values begin with the ID: prefix.
 
JMSPriority
 
This fields defines the importance of a message. The higher the priority value you assign to a message, the faster it will propagate when compared to messages with lower priorities. There are ten levels defined for JMSPriority- 0 to 9. Level 0-4 indicate normal priority, while levels 5-9 indicate expedited priority. A level of 4 is the default for most message providers.
 
JMSRedelivered
 
This field indicates that the current message is a duplicate of a previous message that was delivered to the client, but not acknowledged. This field is set using the send() method of the QueueSender interface or the publish() method of the TopicPublisher interface.
 
JMSReplyTo
 
This field indicates where the recipient of the current message should send a response. Like the JMSDestination field, this field can contain either a queue or a topic. If the JMSReplyTo field is null, then no reply is expected and the message is referred to as a JMS datagram. This field is set using the send() method of the QueueSender interface or the publish() method of the TopicPublisher interface.
 
JMSTimestamp
 
This field is initialized by the message provider and set to the time the message was sent. It contributes a little to the overhead , and if not required , can be set to null, thereby increasing performance.
 
JMSType
 
This field specifies the message type . The JMS specification does not specify a naming syntax, and it is entirely up to the application programmer or the vendor to use a set of possible values. It is recommended that this field be used and not left null. This field is set using the send() method of the QueueSender interface or the publish() method of the ToipcPublisher interface.
 

Setting JMS Header Fields

 
The header fields are set using the associated setter and getter methods, which are part of the Message interface. For instance , the getter and setter associated with JMSMessageID are getJMSMessageID() and setJMSMessageID(). You can set most of the header fields in the send() or the publish() method; others are set by the JMS client and JMS publisher.
 
Source Code
  1. try  
  2. {  
  3.    //Initializing the Factory  
  4.    queueConnectionFactory=(QueueConnectionFactory) context.lookup(“jms/myQueueConnectionFactory”);  
  5.    queue=(Queue)context.lookup(“jms/myQueue”); //Get the queue  
  6. }  
  7. catch(NamingException ex)  
  8. {  
  9.    ex.printStackTrace();  
  10. }  
  11. //Creating producer for sending messages  
  12. producer=queueSession.createProducer(queue);  
  13. //Creating a text Message  
  14. TextMessage textMsg=queueSession.createTextMessage();  
  15. msg=”JMS”;  
  16. textMsg.setText(msg);  
  17. textMsg.setJMSReplyTo(queue);  
  18. //Set the JMSMessageID header field to 100067  
  19. textMsg.setJMSMessageID(“100067”);  
  20. producer.send(textMsg);  
In this source code, the JMSReplyTo and JMSMessageID are set by calling their respective setters on a TextMessage object. The message is sent only after these header fields are set.
 

Message Properties

 
Message property fields are like message header fields, except that they can be set only by the sending application , and not by the client. These fields are set to Read-Only when the message is received by a client and if the client tries to change any value, a MessgaeNotWriteableException will be thrown.
 
Property fields are simple name/value java pairs. The message selector syntax specifications define the naming pattern for these property fields. Some of the valid property types are Boolean, byte, short, int, long, float, double, string.
 
Property fields are important as they can be used by the MessageConsumer to select and filter messages by interrogating the property field. Each of these message property types have corresponding getters and setters. For example, the getters and setters for boolean and String property types are setBooleanProperty() and setStringProperty(). The getters and setters for other properties follow the naming convention.
 
Although the JMS specification does not define a policy for making attributes into message property fileds, JMS providers handle message properties less efficiently than data inside a message body. This means that applications should use message properties only to customize message headers, for example. for customized message selection and filtering.
 
Source Code
  1. TopicSession topicSession=null;  
  2. TopicPublisher topicPublisher=null;  
  3. TextMessage message=null;  
  4. String messageType=”ComputerScience”;  
  5. topicSession=topicConnection.createTopicSession(true,0);  
  6. topicPublisher=topicSession.createPublisher(topic);  
  7. message=topicSession.createTextMessage();  
  8. message.setStringProperty(“Department”, messageType);  
This code illustrate a situation where a provider will only consume a message if the DepartmentID is set to ComputerScience. The setStringProperty() method is used by the message provider to set the DepartmentID property to ComputerScience for the current message. The consumer can use the getStringproperty() method to query whether the message is of the required type.
 
Message Persistence
 
Depending on the needs of your application, JMS offers two method delivery modes,
  • NON-PERSISTENT
  • PERSISTENT
NON-PERSISTENT delivery mode does not guarantee message delivery and messages are not backed up. If the JMS server fails, messages may be lost. The NON-PERSISTENT mode offers significantly lower overheads and better performance.
 
The PERSISTENT mode offers a guarantee that the message will be delivered and will not be lost after it has been sent by the MessageProducer. However , this mode has higher overhead and is slower than the NON-PERSISTENT mode.
 
Messages may get lost even while using the PERSISTENT mode, as expiration times and JMS resource limits may effect the ability of JMS to guarantee message persistence. To ensure that these factors do not hamper message delivery, it is advisable to produce and consume messages within the same transaction while using PERSISTENT delivery mode.
 
Source Code
  1. TopicSession topicSession=null;  
  2. TopicPublisher topicPublisher=null;  
  3. TextMessage message=null;  
  4. String messageType=”ComputerScience”;  
  5. topicSession=topicConnection.createTopicSession(true,0);  
  6. topicPublisher=topicSession.createPublisher(topic);  
  7. message=topicSession.createTextMessage();  
  8. message.setJMSDeliveryMode(DeliveryMode.NON_PERSISTENT);  
This code illustrate the setting up of a message’s delivery mode to NON_PERSISTENT using the setJMSDeliveryMode() method. The setJMSDeliveryMode() and getJMSDeliveryMode() methods are part of javax.jms.Message interface and enable you to set and obtain the JMS delivery mode of the message. The default delivery mode of a message is PERSISTENT.
 

Summary

 
The message header fields are set by the JMS provider and MessageProducer to convey extra information about the message to the MessageConsumer. Unlike message header fields, message property fields can only be set by the sending application and not the client. JMS provides both PERSISTENT and NON-PERSISTENT modes of message delivery.


Similar Articles