About Us

Home >Technology > Full Story


Java Message Service (JMS) defines a standard API that allows Java developers to easily build enterprise applications. A overview of this technology

As opposed to regular request/reply based communication in traditional client/server systems, messaging provides more flexibility and scalability

Internet-based software solutions require a fast, reliable and scalable link between broad variety of newly developed legacy applications and data sources. Communication in this loosely coupled environment is made possible by a specific type of middleware called MOM. The process of integrating an application with other applications which are not meant for Internet is a daunting task.

Messaging for large organizations has been via EDI or proprietary messaging middleware products like IBM MQ Series and TIBCO RV. Both are difficult to configure and maintain with high overheads.

Asynchronous messaging is a proven communication model for developing large-scale, distributed enterprise applications. As opposed to regular request/reply based communication in traditional client/server systems, messaging provides more flexibility and scalability because senders and receivers of messages are de-coupled and are no longer required to execute in lockstep.

The Java Message Service (JMS) defines a standard API that allows Java developers to easily build enterprise applications. JMS is important in its own right because it provides a simplified and common way for Java clients to access message-oriented middleware. More importantly, JMS is tightly integrated into J2EE and is the messaging standard for Enterprise Java Beans (EJB).

From an application design perspective, message-based application design can be categorized into three basic domains:

1. Point-to-point messaging: Point-to-point design is a many-to-one paradigm, where many clients can send messages to a single client. The same client can be a sender, receiver, or both sender and receiver. The working of this communication in JMS is based on the concept of a "queue." Senders put messages into a queue and receivers take messages out. The queue has optional persistence built in to save the messages. The working can be compared to an e-mail. Many people can send e-mails to your address and you retrieve them one after the other from the mailbox. The mail server stores the e-mails until they are retrieved.

2. Publish-subscribe messaging: Publish-subscribe messaging is a many-to-many paradigm. It is the design used when we want multiple applications/clients to receive the same message or when a group of applications want to notify each other. It is like multiple listeners attached to a component. In a JMS message, publishers send messages to a topic, and subscribers receive messages sent to the topic. There can be multiple senders and multiple receivers. The application can again be both a sender and a receiver.

3. Request-reply messaging: Request-reply messaging refers to the design wherein an application sends a message and expects a reply to that message from the receiver. This is a feature rather than a separate design because a point-to-point or publish-subscribe design could also be request-reply based.

JMS doesn't explicitly support request-reply messaging, but allows the use of a "reply to" field in the message. A program can reply to a message by checking this field. This response is optional and left for the client to decide.

Another way of doing this is to create a new queue say, 'acknowledge-queue' to which the client will send an acknowledgement. The requester can retrieve the acknowledgements from this queue.

What is Java Messaging Service API?

The Java Message Service is an API defined by Sun Microsystems. The purpose of JMS is to provide a unified Java-based API to all messaging middleware systems. Developers that use JMS are thus able to write client applications without too much concern about the ultimate message middleware that the clients are going to use. Also, the message system can be replaced with no or few client modifications. JMS follows a Hub and Spoke Topology. In a Hub and Spoke architecture all the applications are connected to a central process called a message server. The message server handles all communication between connected applications called clients. The message server is responsible for routing messages correctly, authenticating and authorizing

user access and guaranteeing the delivery of the messages. Each application client can be a sender, a receiver or both.

JMS supports a point-to-point model and a publish/subscribe model, and it defines a number of message types that publishers and subscribers can exchange. Messages support properties that define how they should be treated by the message system. Subscribes can filter messages using an SQL grammar. Clients can be transient or durable and messages can be sent or received in the context of a transaction.

The JMS is a client API. It only defines how a Java client accesses the messaging capabilities of an enterprise messaging system. Other important aspects of a messaging system including administration and security are not defined by JMS. Each JMS vendor is expected to give support for administration of the messaging system using proprietary methods and tools.

The Concept behind JMS

Fig 2 shows the main concepts in JMS. Although publish/subscribe and point-to-point communication models are very different from a conceptual viewpoint, the models have a lot in common. JMS is therefore centered on a generic messaging model and publish/subscribe and point- to-point models are derived (in the sense of interface inheritance) from the generic model.

The typical steps that a JMS developer performs when developing a client applications are:

1. Resolve a connection factory and a destination from JNDI. A destination is either a queue or a topic.

2. Create a connection using the connection factory.

3. Create a session with the desired properties from the connection.

4. If the application is a supplier, create a MessageProducer; if the application is a consumer, create a MessageConsumer from the session.

5. Start to send or receive messages using the producer or consumer object. A producer will use the session to create different kinds of messages.

JMS supports six different kinds of messages, which are used to carry different types of payload/data. The header of a message is the same regardless of payload, which means filtering is same for all six different message types. A message supports number of properties to set priority, reliability and other QoS properties, which will be interpreted and handled by JMS. In order to properly support durable messages, JMS uses the notion of a durable subscriber. This is only necessary in the publish/subscribe model as messages on a queue will be consumed by any queue receiver that connects to the queue in question. A durable subscriber is identified by a name and the same operation is conveniently used to both create and re-create the subscriber.

JMS, like other Java enterprise APIs, is interface-based and consists of two parts: the client interfaces that the application programs use and the provider that implements the services. The provider can use any underlying mechanism it chooses. In JDBC, for example, applications use the client interfaces and the driver provides implementations using anything ranging from raw sockets to a SQLnet protocol.

The JMS implementation of point-to-point and publish-subscribe paradigms uses these same fundamental concepts, but has specialized classes to handle them. The architecture consists of a common set of base interfaces and at least two sub interfaces for each base interface-one for the point-to-point model, the other for the publish/subscribe model.

What are Administered Objects?

An administered object is an object that the application program retrieves from the JNDI context and works with as though it were a local object. The application administrator uses a vendor provided tool or mechanism to configure these objects. This is similar to the way long-distance telephone carriers work. The phone company can configure the administered "carrier" object as BPL or MaxTouch for example. To the client, the call will work the same way (until the bills come!) and he doesn't have to buy a new telephone set every time he changes his mobile plan.

What is the Destination Interface?

Destinations represent an abstraction of a message delivery or endpoint. The Destination interface is used by the provider to define the location where messages are delivered; the provider will decide the underlying implementation mechanism. The clients never see the details but, this interface works with the sub interfaces javax.jms.Queue and javax.jms.Topic, depending on the message style. The Destination is an administered object.

Getting connection to a Provider: The ConnectionFactory is an abstraction used to encapsulate the specifics of connecting to a JMS provider from an application. The task of a ConnectionFactory is to create a provider-specific connection to the JMS. This is similar to how the driver manager (java.sql.DriverManager) works in JDBC. The application programmer need only connect with the database-specific driver which returns a connection to the database. The ConnectionFactory is an administered object

Client connecting to a Provider: Depending on the messaging style chosen, the connections are created differently from the ConnectionFactory. However, all connections have to implement the Connection interface and thus methods standard to all JMS connections. A connection should be closed when the program is done using it.

The JMS Session: One of the connection's main jobs-to create sessions-is hidden in its implementation. A session in JMS is single-threaded, which means that any message sending and receiving happens in a serial order, one after the other. For example, if A and B sent C four messages each simultaneously, the session ensures that C is notified one at a time. Although notification is synchronized, it may occur in a different thread from the one that created the session if the program uses the MessageListener (discussed later). Sessions can also provide a transactional context. This context stores messages for delivery until the transaction is committed, in which case all the messages are considered a single atomic unit. If the transaction is rolled back, then all messages are destroyed and the session returns to its initial state.

Non-Transacted Session: There are 3 types of Non-transactional sessions AUTO_ACKNOWLEDGE (The session automatically acknowledges a client's receipt of a message), CLIENT_ACKNOWLEDGE (The client acknowledges a message explicitly by invoking the acknowledge() method in the message) and DUPS_OK_ACKNOWLEDGE (This acknowledgement mode instructs the session to acknowledge the delivery of messages).

Sending a message: To send a message to a destination, a client application must ask the session to create a message producer. The message producer has to implement the javax.jms.MessageProducer interface. The MessageProducer is used to get and set default values that are stored in the message when it is sent. The producer needs to be closed once the work is finished.

MessageConsumer: Message consumers are created by the session for clients that want to receive messages. Message consumers are attached to a destination and are designed to retrieve messages sent to those destinations. Just like other interfaces, depending on the messaging style, the javax.jms.QueueReceiver or javax.jms.TopicSubscriber are used.

Messages: The message consists of the header, the properties, and the body. A message is the actual data sent from the sender to the receiver. Again, although the object implementation is provider-specific, a message implements the javax.jms.Message interface.

Message Selectors and Message Filters: In an enterprise environment, a destination may require filtering on business rules. For example, a Bank-Teller object listening for Bank-Account objects as messages may be required to do something only when the account balance is below $3,000. To support filtering, JMS provides the concept of a selector. A selector is a SQL92 string that is passed to the message consumer. The client can use the selector to decide if the message is of interest. The selector cannot reference the contents of the message but it can access the properties and headers. Some examples of selectors are: amount between 300 and 3000, area code like '333'. From the client's perspective, messages that don't meet the selection criteria simply don't exist.

Message Persistence in JMS: Persistence is the ability of the provider to store messages. The client can mark a message as Persistent if it is crucial, and the provider will store this message until it is delivered to the recipients. A message marked as non-persistent may be lost in the delivery process and should only be used for non-crucial messages. Though persistent messages are more reliable, they take up more storage space. Non-persistent messages are ideal for non-crucial tasks where the application is not affected by delivery failure (such as log files, registry).

Message Time-To-Live: A client can specify a time-to-live value in milliseconds for each message it sends. It is up to the provider to "expire" the message or to ignore this property.

Distributed Transactions in JMS

In addition to supporting transactions in the session, JMS provides support for distributed transactions by using Java Transaction API (JTA). Developers can choose between using JMS without JTA or with JTA by using the separate classes provided with the XA prefix (few of the classes are XAQueueConnectionFactory, XATopicConnectionFactory, XAQueueConnection, XATopicConnection, XAQueueSession , XATopicSession ).

JMS-based communication is a potential solution in any distributed computing scenario that needs to pass data, not references, either synchronously or asynchronously, between application components. It offers a good solution for business integration in heterogeneous environments and for connecting to legacy systems. For example, an enterprise computing strategy can use JMS-based distributed software components as a middleware solution that functions as a bridge among legacy applications. A common application for JMS involves interfacing Enterprise JavaBeans with legacy applications and sending legacy-related data between the two.

When working with JMS, we have quite a few architectural choices and application design factors to consider. If we are working with distributed objects, our choices are usually narrowed down to using RMI, RMI over IIOP, or JMS. JMS may provide advantages over these other techniques, but when using JMS many factors (such as performance, load balancing, and clustering) depend on which provider and underlying implementation you choose.

Ajay Barvey is a Senior Programmer with Plexus Technologies and can be reached at ajay_barvey@yahoo.com


- <Back to Top>-  

Copyright 2001: Indian Express Group (Mumbai, India). All rights reserved throughout the world. This entire site is compiled in Mumbai by The Business Publications Division of the Indian Express Group of Newspapers. Site managed by BPD