Developing a JMS application

A Java program with JMS needs to execute the following steps to be able to produce and consume messages in either publish/subscribe or Point-To-Point:

  1. Look up a ConnectionFactory object through the Java Naming and Directory Interface (JNDI).
  2. Look up one or more Destination objects through the JNDI.
  3. With the reference of the ConnectionFactory object, create a Connection object.
  4. With the help of the Connection object, create one or more Session objects.
  5. With the help of the Session and Destination objects, create the required MessageProducer and MessageConsumer objects.
  6. Start Connection.

Once you execute the preceding steps, the program will be able to exchange the messages and receive, process, and send messages as designed. Let's review a few more API components before we write sample programs to exchange messages.

JMS offers numerous message types for diverse forms of content; however, all such messages originate from the Message interface. Message contains the header, properties, and body, which are the essential parts in a Message. Refer to the following points:

  • Message header: This carries important information related to the message. Some important attributes of a message header include JMSMessageID, JMSDestination, JMSDeliveryMode, JMSTimestamp, JMSExpiration, JMSPriority, JMSCorrelationID, JMSReplyTo, JMSType, and JMSRedelivered.
  • Message properties: JMS has defined a set of standard properties for Message to uniquely define a message, including JMSXUserID, JMSXApplID, JMSXDeliveryCount, JMSXGroupID, JMSXGroupSeq, JMSXProducerTXID, JMSXConsumerTXID, JMSXRcvTimestamp, JMSXState, and JMSX_<vendor_name>.
  • Message body: Based on the different types of message content to be carried, the following are the interfaces that extend the Message interface:
    • StreamMessage: This comprises a stream of Java primitive values stored and read successively with standard Java I/O stream operations
    • MapMessage: As the name suggests, this message can contain a set of name-value pairs with string names and Java primitive values
    • TextMessage: This simple form of Message stores it as a java.lang.String
    • ObjectMessage: This stores a serializable Java object as its content
    • BytesMessage: This stores a stream of uninterpreted bytes that can encode a body to match the existing message format
  • Message transactions: A JMS transaction is an atomic unit of work that assembles a set of produced/consumed messages. If an error/exception occurs during the execution of a transaction, the entire message production/consumption that is considered part of this transaction should be rolled back. Session objects control transactions, and a Session object may be denoted as transacted when it is created. A transacted Session object always has a current transaction, that is, there is no begin(), commit(), and rollback(); it always ends one transaction and automatically begins another. With the help of the Java Transaction API (JTA) XAResource API, distributed transactions are supported; however, not all providers support XA transactions. I have had the experience of working with the Apache ActiveMQ, IBM WebSphereMQ, and the Solace message queue systems. Solace system, though the latest of all, is not entirely comfortable with XA transactions.
  • Message acknowledgment: When a message consumer receives a message and processes it successfully, it can inform the provider about the processing status. If the Session object receiving the message is transacted, an acknowledgment is handled automatically. If it is not transacted, then the type of acknowledgment is determined when Session is created. There are essentially three types of acknowledgment mode:
    • Session.DUPS_OK_ACKNOWLEDGE: This is a lazy acknowledgment of message delivery. It allows duplicate messages to pass through and hence should be selected only if duplicates are expected and can be handled.
    • Session.AUTO_ACKNOWLEDGE: In this mode, message delivery is automatically acknowledged to the provider upon completion of the method execution that receives the message.
    • Session.CLIENT_ACKNOWLEDGE: In this mode, message delivery is explicitly acknowledged by calling the acknowledge() method on Message.

There's an important task with the CLIENT_ACKNOWLEDGE mode that needs to be performed: advising your clients not to have a huge number of unacknowledged messages before they begin processing the messages. This situation is called as resource exhaustion; in this case, the processing of the resources that are temporarily blocked might fail.

The recover method of Session can be called by the client to request the provider to stop a session and restart it by sending the first unacknowledged message before terminating the session with the recover method. With this option, the session's message queue is reset to a point after its last acknowledged message. The order/series of messages the provider delivers after the recovery may be different from those that were delivered before. This is due to message expiration and the arrival of new high-priority messages. A Session must set the redelivered flag of the messages that the provider is redelivering due to a recovery being called.

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

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