[an error occurred while processing this directive]
> developer > web app development
Getting Up to Speed with Java Message Service (JMS)
by exteNd Composer Product Team, eBusiness Integration Products, Novell
Date Created: 2001-02-23 15:31:00.000
  Introduction
  What Is JMS, Really?
  What Is Enterprise Messaging?
  What Are Message Queues?
  Are Message-Based Applications Slow?
  Is Messaging Reliable?
  Can Messages Be Part of Transactions?
  Point-to-Point Messaging
  What About Delivery Guarantees?
  How Are Messages Structured?
  Header Information
  Body Types
  How Are Messages Retrieved?
  Message Filtering
  Request-Response versus Store/Forward
  What Does JMS Not Cover?
  About xCommerce's JMS Component
  Conclusion
introduction
Java Messaging Service (JMS), Sun's Java interface for access to Message Oriented Middleware (MOM) services, is an increasingly important standard in the world of J2EE computing. Yet because of its newness, JMS is still not terribly well understood by application developers. In this article, we'll try to demystify JMS while providing a crash course in message-oriented middleware (MOM) concepts. Along the way, we'll have occasion to mention SilverStream Software's xCommerce JMS Enterprise Enabler and talk briefly about how it allows the designer of XML integration applications to leverage the power of messaging. By the end of the article, you'll have a solid grasp of MOM fundamentals and how JMS fits into the J2EE puzzle.
what is JMS, really?

In order for distributed applications running on Java application servers to make full use of messaging systems (such as IBM's MQSeries or Progress Software's SonicMQ), Java-language clients and Java middle-tier services must have a common way to "talk to" enterprise messaging products. JMS provides that capability. In essence, JMS is an abstraction layer that lets the Java programmer create MOM-facing elements without having to know the low-level particulars of any vendor's solution.

The JMS standard was built with several goals in mind:

  • Provide an Application Programming Interface suitable for creating and manipulating messages in formats compatible with existing MOM products.
  • Support many different message-content types, including messages containing Java objects.
  • Facilitate the development of heterogeneous applications that span operating systems, machine architectures, transport mechanisms, and computer languages.

JMS is a broadly applicable Java API that is intended to be layered over a wide range of existing and future Message Oriented Middleware systems, much the same way that JNDI (the Java Name and Directory Interface) is layered over existing name and directory services.

The complete JMS specification is available at http://java.sun.com/products/jms/.

what is Enterprise messaging?

An enterprise messaging system provides for the transport and storage of messages. Messages, in this context, are packets of information that are produced and/or consumed primarily by enterprise applications (rather than humans). They may contain key-value pairs, XML documents, serialized Java objects, or arbitrary byte streams.

One of the main attractions of Message Oriented Middleware is its ability to hide the details of message transport and delivery from diverse clients that may need to communicate across networks that use different communication protocols. By acting as a communications gateway, MOM shields clients from connectivity issues that would otherwise impede development of distributed applications.

The other aspect of enterprise messaging that makes products like MQSeries and SonicMQ so powerful is their ability to link processes in asynchronous fashion. Asynchronous processing means that the exchange of data between parties does not depend on either party being in direct, realtime contact with the other. The alternative to asynchronous processing is synchronous processing, wherein a host and a client (or a peer and a peer) must be in continuous conversation with each other for the entire duration of a session, without interruption. (An example of a synchronous interchange would be the use of a Remote Procedure Call in a CICS environment.)

While synchronous sessions are essential for some types of business logic, there are also many kinds of business processes that do not require synchronous communication between participants. For those processes, asynchronous interaction generally makes the most efficient use of resources and can dramatically improve system productivity.

A synchronous process is analogous to a restaurant in which every customer orders his meal directly through a conversation with the chef and the kitchen takes no other orders while the current customer's meal is being cooked. Customers line up and must wait, one by one, for every meal to be invidiually prepared. Asynchronous processing would be analogous to the more familiar scenario of waiters and waitresses conveying orders between customer and, kitchen concurrently. In the latter case, the waiters serve as a messaging channel to the kitchen, where orders are "queued up" and finished meals are dispersed on an as-available basis. In this example (as in many business processes), much better efficiencies are possible with asynchronous order processing than with synchronous order processing.

The time-domain decoupling afforded by messaging systems helps make robust, fail-safe operation possible. One party can be busy, or even offline, when the other party sends (or receives) its message. A network or server can go down, yet not affect the transmission or receipt of a message.

what Are message queues?
Asynchronous messaging depends on the fact that messages are sent not to clients, per se, but to queues, which exist independently of the client processes that use them.

A queue is a holding area or repository in which data elements (messages, in this case) are stored for eventual retrieval. In a MOM environment, client applications needn't know how message queues are structured, maintained, or stored; the details of queue management are handled by the MOM vendor (or "JMS provider"). Like server nodes, queues are often clustered for purposes of reliability, scalability, and load balancing.

While FIFO (first-in/first-out) and LIFO (last-in/first-out) queues are familiar constructs in computing, no order of retrieval is presumed in a message queue. Rather, the retrieval order is open. This means custom prioritization schemes can be applied to messages so that retrieval order (i.e., consumption order) is dependent on a client's needs. Properly exploited, this feature can lead to more efficient overall system operation. Processing of low-priority messages can be deferred to a time when system resources are available; low-priority items needn't interfere with the processing of high-priority ones.

You should note that the length of time messages are held in a queue, the maximum number of messages a queue can handle, and the manner in which resource overruns are handled are not defined by the JMS standard. The MOM vendor's documentation is the place to learn more about these issues.

are message-based applications slow?
While some latency occurs in all messaging systems, this does not mean that applications that use messaging are, of necessity, slow. Depending on the installation, throughputs of many hundreds of messages per second are possible. The important thing to keep in mind is that the asynchronous processing made possible by messaging affords the possibility of multitasking for applications that otherwise might not have that capability. This can boost throughput significantly (as in the restaurant example mentioned earlier). While a customer adds items to his shopping cart, the shopping-cart app can trigger an inventory-checking component, while another component can calculate shipping charges, while another component pulls customer information out of a database, etc., all operations taking place concurrently.
is messaging reliable?
While the quality-of-service guarantees offered in Message Oriented Middleware solutions can vary greatly, and while real-world reliability often depends on administrative issues (such as cluster size and available resources), all JMS-based messaging services are required to offer assured, once-only delivery of messages as an option for applications where reliability is paramount. JMS also allows for configurations that provide a less robust quality of service, so that in cases where speed of delivery might be more important than assured, once-only delivery, a tailored solution can be built. The reliability of JMS-based messaging solutions is thus configurable.

In general, strong reliability guarantees are a common feature of JMS-based systems.

can messages be part of transactions?
One of the things that makes JMS messaging attractive is that message sessions can optionally incorporate transaction control. A transacted session groups an arbitrary set of produced and/or consumed messages into a single logical unit of work. When a transaction commits, all of its inputs (in terms of messages) are acknowledged and all outputs are sent. When a transacted message session rolls back, any produced messages are destroyed and any messages consumed during the session are recovered.

An an example, suppose an application builds a group of five messages. A requirement of the application is that the entire group of five messages must be sent as a batch; or else none of the five must be sent. Using an xCommerce JMS Component, the application could be structured such that messages are built and sent individually, but if a connection closes prematurely (or any other error condition happens, involving any of the five messages), the entire group is rolled back. NOTE

JMS does not require that MOM products support distributed transactions. But if such support exists, JMS does require that such support be implemented via the JTA (Java Transactions API) XAResource interface. Consult the JMS provider's documentation to see what kind of distributed transaction support, if any, is available in a particular MOM environment.

Since distributed transactions are controlled via JTA/XAResource, the use of JMS commit or rollback commands in a JTA context will cause a JMS TransactionInProgressException to be thrown.

point-to-point messaging

Two main messaging paradigms are implemented by MOM vendors: Point-to-Point (PTP) messaging, and Publish/Subscribe (which is discussed further below). Some vendors implement one or the other; some implement both.

Note that Point-to-point does not imply a synchronous connection in the context of messaging (as it does in some other contexts, such as discussions of RPC).

In the PTP model, any JMS client can, in theory, send messages to any other JMS client, subject only to administrative constraints. PTP is an asynchronous, queue-based, peer-to-peer model in which queues are created administratively and have indefinite lifespans. A queue is always available to receive and hold messages sent to it whether the client or clients using that queue are online or not. This is what makes messaging asynchronous.

With PTP, a queue functions much like a mailbox. One application might send messages to a queue; another application might retrieve messages from the same queue. A common case is that a client will have all its messages delivered to a single queue.

Publish/Subscribe Messaging

The Publish/Subscribe (or pub/sub) messaging model, implemented by some (but not all) MOM vendors, differs from Point-to-Point in the following ways:

  • Queues are typically shared by multiple clients.
  • Queues are organized hierarchically into nodes called topics. (This is a typical implementation scheme, although in fact JMS places no restrictions on what a topic can represent.)
  • Each topic acts as a kind of mini-message-broker that accumulates and distributes messages addressed to it.

Clients in this kind of system use message producer/consumer objects called TopicPublishers and TopicSubscribers. A client may subscribe to more than one topic; and a client may be both a subscriber and a publisher.

TopicSubscribers can be durable or non-durable. If a client needs to have access to all messages on a given topic (including ones that may be published when the subscriber is offline), a durable TopicSubscriber must be used. Otherwise, the client will have access only to messages that are queued during the lifetime of a given message-retrieval session.

Messages are served to subscribers in serial fashion. Because topics are shared resources (and because only one subscriber can be serviced at a time), the potential for latency is somewhat greater in pub/sub messaging than in PTP.

what about delivery guarantees?

JMS supports two modes of message delivery.

  • The PERSISTENT mode instructs the message broker to write the message to a secure store to insure that the message is not lost in transit due to a system failure.
  • The NON_PERSISTENT mode does not require the JMS provider to log the message to stable storage; thus, the message can, in theory, be lost. (The tradeoff here is one of performance. There is less overhead with a NON_PERSISTENT message.)

A JMS provider is required to deliver a NON_PERSISTENT message at-most-once. This means that while a message may sometimes be lost, it will never be delivered twice.

By contrast, the delivery guarantee for PERSISTENT messages is once-and-only-once. This means a provider failure must not cause a message to be lost in transit; and the message must not be delivered more than once. NOTE

Once-and-only-one delivery has the important limitation that it cannot and does not guarantee against message loss due to message expiration, resource overruns, or administrative destruction criteria. Configuring a message system for maximum reliability requires a thorough understanding of administrative issues surrounding the particular MOM solution in use.

how are messages structured?
Enterprise messaging products treat messages as persistible, lightweight entities that consist of a header, a body, and (in the case of JMS-aware products) a property list.The header contains fields used for message routing and identification. The body contains the application data being sent. Properties provide a mechanism for adding arbitrary descriptors (actually implemented as extra header fields) to messages so that clients, or their providers, can select or "filter" messages on the basis of application-specific criteria.
header information

Among the message characteristics defined in the header are an expiration time (which sets the message's useful life); message priority (based on a number ranking, from zero to nine); and delivery mode (PERSISTENT or NON_PERSISTENT).

The header fields defined by JMS are:

JMSCorrelationID

JMSDestination

JMSDeliveryMode

JMSExpiration

JMSPriority

JMSMessageID

JMSTimestamp

JMSRedelivered

JMSReplyTo

JMSType

The meanings of the fields are as follows.

JMSCorrelationID

A JMS client can use the JMSCorrelationID header to associated one message with another (for request/response situations). This field can hold an arbitrary string value, obtained by mapping a node value from an Input DOM, or perhaps created dynamically with the aid of ECMAScript, etc. Use of this field is not mandatory.

JMSDeliveryMode

This header field contains the delivery mode (PERSISTENT or NON_PERSISTENT) specified when the message was sent. At the start of a send session, this header field is ignored; after the send has been accomplished, it holds the delivery mode specified by the sending method.

JMSDestination

The JMSDestination header field is ignored at the time a message is sent; after the send, it contains the destination object specified by the sending message.

You do not need to enter anything manually in this field, since the necessary connection information (i.e., choice of destination queue) was automatically set when you first created the JMS Component.

JMSExpiration

This contains the Time-to-Live value for the message, specified in milliseconds. If it is zero, the message will have no expiration value (which means it will not expire).

Note: In most JMS-based MOMs, clients never receive expired messages.

JMSMessageID

The JMSMessageID value uniquely identifies a message in the MOM environment. It is set automatically by the JMS provider and is read-only (and only after a message has been sent).

JMSPriority

The JMSPriority field holds a string value containing one of ten values ('0' through '9') reflecting the message's priority. What prioritization actually means in a given MOM system is vendor dependent.

JMSRedelivered

If a client application receives a message that has the JMSRedelivered marker set, it is possible that the queue manager tried to deliver the message earlier, but the message was not acknowledged by the client (perhaps due to a system failure). This field is under the control of the queue manager or message broker. It is not under application control.

JMSReplyTo

The JMSReplyTo field is designed to contain a Destination supplied by a client when a message is sent. It represents the destination where a reply to the message (if any) should be sent.

JMSTimestamp

This field contains the time that a message was handed off to a provider to be sent. It may or may not be the actual transmission time, depending on whether (for instance) the message's "send" session is under transactional control.

JMSType

This user-settable field contains an arbitrary string supplied by a client when a message is created. The sender can assign any value to JMSType that a receiver might find useful. For example, application-defined JMSType values could facilitate message filtering by making it possible for various receivers to handle various specific message types. NOTE

Some JMS providers store message type definitions in a repository and may expect runtime values in JMSType that correspond to these type definitions. When this is the case, one should use symbolic values for JMSType that correspond to legal values defined in the applicable repository. (Consult the appropriate vendor's documentation for details.)

In addition to these predefined header fields (which every JMS message is required to have), there are JMS-defined property fields (many of which are optional), provider-specific properties, and user proprties.

body types

JMS defines five message body types:

  1. MapMessage-a message in which the body consists of a set of key-value pairs, wherein the keys are Java Strings and the values are Java primitive types. Entries may be accessed by sequential enumeration or randomly by name. (The ordering of key-value pairs is undefined.)
  2. TextMessage-a message in which the body is a java.lang.String.
  3. StreamMessage-a message whose body consists of a stream of Java primitive values (which are filled and read sequentially).
  4. ObjectMessage-a message containing a Serializable Java object. (For collections of objects, one of the collection classes defined in JDK 1.2 can be used.)
  5. BytesMessage-a message comprising any arbitrary stream of uninterrupted bytes. (This category is intended for literally encoding a body to match a vendor's native message format.)
NOTE

Regardless of type, all JMS messages are read-only once posted to a queue.

SilverStream's JMS Enterprise Enabler for xCommerce allows you to define message payloads using any of the five canonical JMS body types. In addition, the JMS Enterprise Enabler offers two predefined message types (which are actually wrappers for two of the predefined JMS body types):

XML: Allows the xCommerce application to send or receive an XML document (based on any XML template of your choosing) as a message. The complete DOM representation of the XML document is available to you for mapping and/or manipulation via ECMAScript and XPath; and you can add new nodes to the template document. This message type wrappers the JMS- defined TextMessage type.

Copybook: Allows the xCommerce application to send or receive a COBOL copybook (as a BytesMessage).

how are messages retrieved?

JMS provides two mechanisms for client retrieval of messages:

Synchronous message retrieval, wherein a timeout value can be specified for terminating the session should no response occur.

Asynchronous retrieval via a MessageListener object whose onMessage() method contains application logic for processing incoming messages.

Here, the terms "synchronous" and "asynchronous" refer to the queue/client communication session rather than any relationship between sender and client. Senders can always post to queues, whether or not receiving clients are online; in that sense, all messages are asynchronously received.

In synchronous retrieval, a timeout value can be specified in milliseconds. If no expiration value is specified, the "receive" session will block indefinitely, until a message arrives. On the other hand, if a zero wait time is specified, queued messages that meet the applicable selection criteria (if any) will be retrieved-and the session terminated-immediately.

Asynchronous retrieval treats messages like events and allows clients to be notified immediately (and take action on) messages as they arrive. Application logic triggered by an onMessage() handler processes messages transparently, with a minimum of latency. A broadcaster/listener metaphor applies.

One way to think of it is that in a synchronous-retrieval scenario, the client is pulling data from the queue, whereas in the asynchronous case, the queue is pushing data at the client.

message filtering
Some applications need to filter and/or categorize the messages they send or receive. In some instances, the receiving application can simply inspect the message body and decide-from the message contents-whether the message should be acted upon, or discarded. But it is often more efficient for selection criteria to be exposed in the message header, so that the message body need not be parsed in order to determine if the message is one that should be acted upon.

Exposing message selection hints in the header portion of a message is a common tactic when multiple receiving apps are pointed at the same queue. The application that is best suited to handling a given message type can harvest just the messages it needs, while other applications can act on messages better suited for them. Administratively, it is more efficient to set up one queue (with multiple receivers accessing it) than to set up multiple queues, each with a dedicated receiver.

JMS defines a message selector that can be used for screening messages on a queue. The selector is an expression (with syntax similar to SQL92) that evaluates to true or false when header field and/or property values are substituted for their corresponding identifiers in the selector.

The xCommerce JMS Enterprise Enabler implements selectors in the Message Filter tab of the Native Environment pane for all Browse and Receive actions; this allows you to filter incoming messages according to whatever criteria you select.

request-response versus store/forward
A request-response scenario involves an application sending a message in anticipation of receiving a reply. For example, a credit-clearing application might package customer information into a message and send that message to a queue, where a receiving application retrieves the message, performs the necessary database queries and other processing, then replies to the original message.

This is different from the store/forward or "fire and forget" type of scenario in which a message producer simply places a message on a queue and terminates (or goes on to other processing). Messages that are sent in this fashion are sometimes called datagrams.

what does JMS not cover?

The JMS standard defines numerous message-system behaviors and data types but does not address administrative concerns, performance tuning, security, configuration issues, nor a variety of other JMS-provider functions.

Among the areas not addressed by JMS are:

  • Load balancing
  • Scalability
  • Transparent failover
  • Sytem-wide error notifications or warnings
  • User authentication
  • Secure transport of messages (privacy)
  • Communications protocols
  • Message type definitions stored in a repository

Consult the MOM vendor's documentation for information about any of these features.

about xCommerce's JMS component
Novell's xCommerce JMS Enterprise Enabler allows the creation of JMS Components that can be incorporated into xCommerce services. Much like the XML Map Component, the JMS Component is designed to map, transform, and transfer data between incoming or ooutgoing messages and XML templates. It is specialized to make JMS calls into JMS-aware messaging systems; automatically fill out needed header information based on information you supply via a setup wizard; and handle details of packaging message contents according to constraints imposed by JMS.

The JMS Enterprise Enabler is a powerful addition to the xCommerce product line. It means that XML integration applications can leverage the power of messaging, without the application designer having to know the nitty-gritty details of a particular vendor's MOM solution. In short: a lot of gain for not much pain.

conclusion
Enterprise messaging can been around for years and won't be going away any time soon. It provides valuable connectivity services to systems that need to communicate across diverse transport systems, and gives applications asynchronous access to back-end systems, thus freeing up those systems.

By exposing a standardized Java interface to message-oriented middleware, JMS lets application developers bring the power of messaging to the world of J2EE. Everybody wins.