Skip to main content

If you don't have an IBM ID and password, register here.

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. This profile includes the first name, last name, and display name you identified when you registered with developerWorks. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

All information submitted is secure.

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

Introducing the Java Message Service

author photo
Willy Farrell is a senior software engineer in the IBM Developer Skills Program. As part of the developerWorks team, he provides relevant technical information and insight to developers on the latest e-business and industry trends through Web content, articles, speaking engagements, and consulting to faculty at IBM Scholars Program member universities. He has been programming computers for a living since 1981, began using Java in 1996, and joined IBM in 1998.

Summary:  This tutorial provides an introductory overview of the Java Message Service, its functionality, and its capabilities. You will learn the basic programming techniques for creating JMS programs and work with sample code that demonstrates these techniques. Note: This tutorial has been updated to include changes to JMS version 1.1.

Date:  08 Jun 2004
Level:  Introductory PDF:  A4 and Letter (157 KB | 44 pages)Get Adobe® Reader®

Comments:  

JMS overview and architecture

Applications

A JMS application comprises the following elements:

  • JMS clients. Java programs that send and receive messages using the JMS API.

  • Non-JMS clients. It is important to realize that legacy programs will often be part of an overall JMS application, and their inclusion must be anticipated in planning.

  • Messages. The format and content of messages to be exchanged by JMS and non-JMS clients is integral to the design of a JMS application.

  • JMS provider. As was stated previously, JMS defines a set of interfaces for which a provider must supply concrete implementations specific to its MOM product.

  • Administered objects. An administrator of a messaging-system provider creates objects that are isolated from the proprietary technologies of the provider.

Administered objects

Providers of MOM products differ significantly in the mechanisms and techniques they use to implement messaging. To keep JMS clients portable, objects that implement the JMS interfaces must be isolated from a provider's proprietary technologies.

The mechanism for doing this is administered objects. These objects, which implement JMS interfaces, are created by an administrator of the provider's messaging system and are placed in the JNDI namespace.

The objects are then retrieved by JMS programs and accessed through the JMS interfaces that they implement. The JMS provider must supply a tool that allows creation of administered objects and their placement in the JNDI namespace.

There are two types of administered objects:

  • ConnectionFactory: Used to create a connection to the provider's underlying messaging system.

  • Destination: Used by the JMS client to specify the destination of messages being sent or the source of messages being received.

Although the administered objects themselves are instances of classes specific to a provider's implementation, they are retrieved using a portable mechanism (JNDI) and accessed through portable interfaces (JMS). The JMS program needs to know only the JNDI name and the JMS interface type of the administered object; no provider-specific knowledge is required.


Interfaces

JMS defines a set of high-level interfaces that encapsulate various messaging concepts. In turn, these interfaces are further defined and customized for the two messaging domains -- PTP and pub/sub.

The high-level interfaces are:

  • ConnectionFactory: An administered object that creates a Connection.

  • Connection: An active connection to a provider.

  • Destination: An administered object that encapsulates the identity of a message destination, such as where messages are sent to or received from.

  • Session: A single-threaded context for sending and receiving messages. For reasons of simplicity and because Session s control transactions, concurrent access by multiple threads is restricted. Multiple Session s can be used for multithreaded applications.

  • MessageProducer: Used for sending messages.

  • MessageConsumer: Used for receiving messages.


Interfaces (continued)

The following table identifies the domain-specific interfaces inherited from each high-level interface.

High-level interface PTP domain Pub/sub domain
ConnectionFactory QueueConnectionFactory TopicConnectionFactory
Connection QueueConnection TopicConnection
Destination Queue Topic
Session QueueSession TopicSession
MessageProducer QueueSender TopicPublisher
MessageConsumer QueueReceiver, QueueBrowser TopicSubscriber

Interfaces: What's changed in JMS 1.1

In previous versions of JMS, the high-level interfaces were parents of the domain-specific interfaces and contained only those functions common to both domains. No implementations of the high-level interfaces were provided by the JMS provider. In JMS 1.1, the high-level interfaces are now considered "common interfaces" and contain all of the functionality of both domains; JMS providers must provide implementations of these interfaces. Although the common interfaces are still parents to the domain-specific interfaces, they are now the preferred method for JMS client programming, and the domain-specific interfaces are provided only for backward compatibility.

The following restates the table on the previous section, showing the common interfaces.

JMS common interface PTP domain Pub/sub domain
ConnectionFactory QueueConnectionFactory TopicConnectionFactory
Connection QueueConnection TopicConnection
Destination Queue Topic
Session QueueSession TopicSession
MessageProducer QueueSender TopicPublisher
MessageConsumer QueueReceiver, QueueBrowser TopicSubscriber

Unification of domains with the common interfaces results in some domain-specific classes inheriting methods that are not suited for that domain. The JMS provider is required to throw an IllegalStateException should this occur in client code.


Developing a JMS program

A typical JMS program goes through the following steps to begin producing and consuming messages:

  1. Look up a ConnectionFactory through JNDI.

  2. Look up one or more Destination s through JNDI.

  3. Use the ConnectionFactory to create a Connection.

  4. Use the Connection to create one or more Session s.

  5. Use a Session and a Destination to create the required MessageProducer s and MessageConsumer s.

  6. Start the Connection.

At this point, messages can begin to flow, and the application can receive, process, and send messages, as required. In later sections, we'll develop JMS programs and you'll get to see this setup in detail.


Messages

At the heart of a messaging system are, of course, messages. JMS provides several message types for different types of content, but all messages derive from the Message interface.

A Message is divided into three constituent parts:

  • The header is a standard set of fields that are used by both clients and providers to identify and route messages.

  • Properties provide a facility for adding optional header fields to a message. If your application needs to categorize or classify a message in a way not provided by the standard header fields, you can add a property to the message to accomplish that categorization or classification. set<Type>Property(...) and get<Type>Property(...) methods are provided to set and get properties of a variety of Java types, including Object. JMS defines a standard set of properties that are optional for providers to supply.

  • The body of the message contains the content to be delivered to a receiving application. Each message interface is specialized for the type of content it supports.


Header fields

The following list gives the name of each header field of Message, its corresponding Java type, and a description of the field:

  • JMSMessageID -- type string

    Uniquely identifies each message that is sent by a provider. This field is set by the provider during the send process; clients cannot determine the JMSMessageID for a message until after it has been sent.

  • JMSDestination -- type Destination

    The Destination to which the message is sent; set by the provider during the send process.

  • JMSDeliveryMode -- type int

    Contains the value DeliveryMode.PERSISTENT or DeliveryMode.NON_PERSISTENT. A persistent message is delivered "once and only once"; a non-persistent message is delivered "at most once." Be aware that "at most once" includes not being delivered at all. A non-persistent message might be lost by a provider during application or system failure. Extra care will be taken to assure that a persistent message is not affected by failures. There is often considerable overhead in sending persistent messages, and the trade-offs between reliability and performance must be carefully considered when deciding the delivery mode of a message.

  • JMSTimestamp -- type long

    The time that the message was delivered to a provider to be sent; set by the provider during the send process.

  • JMSExpiration -- type long

    The time when a message should expire. This value is calculated during the send process as the sum of the time-to-live value of the sending method and the current time. Expired messages should not be delivered by the provider. A value of 0 indicates that the message will not expire.

  • JMSPriority -- type int

    The priority of the message; set by the provider during the send process. A priority of 0 is the lowest priority; a priority of 9 is the highest priority.

  • JMSCorrelationID -- type string

    Typically used to link a response message with a request message; set by the JMS program sending the message. A JMS program responding to a message from another JMS program would copy the JMSMessageID of the message it is responding to into this field, so that the requesting program could correlate the response to the particular request that it made.

  • JMSReplyTo -- type Destination

    Used by a requesting program to indicate where a reply message should be sent; set by the JMS program sending the message.

  • JMSType -- type string

    Can be used by a JMS program to indicate the type of the message. Some providers maintain a repository of message types and will use this field to reference the type definition in the repository; in this case, the JMS program should not use this field.

  • JMSRedelivered -- type boolean

    Indicates that the message was delivered earlier to the JMS program, but that the program did not acknowledge its receipt; set by the provider during receive processing.


Standard properties

The following list gives the name of each standard property of Message, its corresponding Java type, and a description of the property. Support for standard properties by a provider is optional. JMS reserves the "JMSX" property name for these and future JMS-defined properties.

  • JMSXUserID -- type string

    Identity of the user sending the message.

  • JMSXApplID -- type string

    Identity of the application sending the message.

  • JMSXDeliveryCount -- type int

    Number of times delivery of the message has been attempted.

  • JMSXGroupID -- type string

    Identity of the message group to which this message belongs.

  • JMSXGroupSeq -- type int

    Sequence number of this message within the message group.

  • JMSXProducerTXID -- type string

    Identity of the transaction within which this message was produced.

  • JMSXConsumerTXID -- type string

    Identity of the transaction within which this message was consumed.

  • JMSXRcvTimestamp -- type long

    The time JMS delivered the message to the consumer.

  • JMSXState -- type int

    Used by providers that maintain a message warehouse of messages; generally not of interest to JMS producers or consumers.

  • JMSX_<vendor_name>

    Reserved for provider-specific properties.


Message body

There are five forms of message body, and each form is defined by an interface that extends Message. These interfaces are:

  • StreamMessage: Contains a stream of Java primitive values that are filled and read sequentially using standard stream operations.

  • MapMessage: Contains a set of name-value pairs; the names are of type string and the values are Java primitives.

  • TextMessage: Contains a String.

  • ObjectMessage: Contains a Serializable Java object; JDK 1.2 collection classes can be used.

  • BytesMessage: Contains a stream of uninterpreted bytes; allows encoding a body to match an existing message format.

Each provider supplies classes specific to its product that implement these interfaces. It is important to note that the JMS specification mandates that providers must be prepared to accept and handle a Message object that is not an instance of one of its own Message classes.

Although these "alien" objects might not be handled by a provider as efficiently as one of the provider's own implementations, they must be handled to ensure interoperability of all JMS providers.


Transactions

A JMS transaction groups a set of produced messages and a set of consumed messages into an atomic unit of work. If an error occurs during a transaction, the production and consumption of messages that occurred before the error can be "undone."

Session objects control transactions, and a Session can be denoted as transacted when it is created. A transacted Session always has a current transaction, that is, there is no begin(); commit() and rollback() end one transaction and automatically begin another.

Distributed transactions can be supported by the Java Transaction API (JTA) XAResource API, though this is optional for providers.


Acknowledgment

Acknowledgment is the mechanism whereby a provider is informed that a message has been successfully received.

If the Session receiving the message is transacted, acknowledgment is handled automatically. If the Session is not transacted, then the type of acknowledgment is determined when the Session is created.

There are three types of acknowledgment:

  • Session.DUPS_OK_ACKNOWLEDGE: Lazy acknowledgment of message delivery; reduces overhead by minimizing work done to prevent duplicates; should be used only if duplicate messages are expected and can be handled.

  • Session.AUTO_ACKNOWLEDGE: Message delivery is automatically acknowledged upon completion of the method that receives the message.

  • Session.CLIENT_ACKNOWLEDGE: Message delivery is explicitly acknowledged by calling the acknowledge() method on the Message.


Message selection

JMS provides a mechanism, called a message selector, for a JMS program to filter and categorize the messages it receives.

The message selector is a String that contains an expression whose syntax is based on a subset of SQL92. The message selector is evaluated when an attempt is made to receive a message, and only messages that match the selection criteria of the selector are made available to the program.

Selection is based on matches to header fields and properties; body values cannot be used for selection. The syntax for message selectors is provided in detail in the JMS specification.


JMS and XML

The authors of JMS included the TextMessage message type on the presumption that String messages will be used extensively.

Their reasoning is that XML will be a popular, if not the most popular, means of representing the content of messages. A portable transport mechanism (JMS) coupled with a portable data representation (XML) is proving to be a powerful tool in enterprise application integration (EAI) and other areas of data exchange.


JMS and J2EE

J2EE version 1.2 requires compliant application servers to have the JMS API present but did not mandate the presence of a JMS provider.

J2EE version 1.3 requires application servers to supply a JMS provider. J2EE version 1.3 also introduced the message-driven bean, adding asynchronous notification abilities to Enterprise JavaBeans containers, as part of the EJB 2.0 specification. A message-driven bean implements the MessageListener interface (see MessageListener ) later in this tutorial), and is invoked by the EJB container on the arrival of a message at a destination designated at deployment time. Message-driven beans contain the business logic to process the message, including, if needed, invoking other enterprise beans.

J2EE version 1.4 requires J2EE products to include a JMS version 1.1 provider that supports both point-to-point and publish/subscribe messaging. It specifies that J2EE applications will not use the JMS client APIs for transaction handling; transactions will be handled by the J2EE containers. J2EE version 1.4 also requires that components in Web and EJB containers not create more than one active Session per connection.

3 of 13 | Previous | Next

Comments



Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Java technology
ArticleID=131862
TutorialTitle=Introducing the Java Message Service
publish-date=06082004
author1-email=willyf@us.ibm.com
author1-email-cc=

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).