Building Messaging Systems with JMS
To begin with, it's necessary to mention that we expect from the reader a rather solid knowledge of Java programming to understand this article. We will try to easily explain what JMS is, but before you can create your own programs and understand them correctly, you need to have experience in developing real applications working with JNDI.
JMS (Java Message Service) is a standard of message exchange that allows J2EE application components to create, send, receive, and read messages. It supposes that the distributed communications have a free connection, reliable and asynchronous.
The Exchange System
The message exchange represents a way of interaction between program components or applications. The system of message exchange is a system with equal rights: The client of a similar system can both send and accept messages from any other client. Each client incorporates to the agent of the system that provides an opportunity to create, send, accept, and read messages.
The exchange system makes the distributed interaction possible. The component sends the message in Destination, and the addressee can take this message from the same Destination. Nevertheless, the sender and the addressee should not necessarily be accessible at one time to cooperate with each other. In other words, the sender is not obliged to know something about the addressee and the addressee is not obliged to know something about the sender. The sender and the addressee should know only about what format of messages and what Destination to use. In this respect, the described system differs from technologies closely connected to it, such as Remote Method Invocation (RMI), demanding from the application a knowledge of the remote application's methods.
The Messaging System
Messaging System—is a distributed system based on an asynchronous messages exchange between system components. Message-Oriented Middleware (MOM) is that product, on the basis of which Messaging System is built.
Messaging System applications do not communicate directly (in comparison to traditional systems (RMI based)), but with the help of MOM. If one component of the system wants to send the message to another component, it sends the given message to MOM, and MOM then sends the message to the addressee.
The following advantages compare with the traditional systems constructed on basis of RMI:
- The application that sent the message should not expect a reply, and can continue activity.
- Neither the application that sent the message nor the addressee of the given message are obliged to be active at a given time. If the message addressee is not active, MOM guarantees that the message will be delivered as soon as the addressee becomes active.
- System components are not connected directly with each other. They are decoupled; that is why transferring components from one host on another in runtime is possible without breaking the system's serviceability.
The Models of Exhange: Point-to-Point and Publish-Subscribe
There are two "basic" models of message exchange: the point-to-point model and the publish-subscribe (pub-sub) model. A point-to-point model is applied when it is necessary for one or several component senders to send the message only to one component, the addressee (receiver). The model is based on the concept of a message queue: Senders send messages into the queue, and the receiver reads messages from this queue. In the point-to-point model, several receivers can exist, attached to the same queue. However, MOM will deliver the message only to one of them. To which depends on the MOM implementation.
A publish-subscribe model is applicable when it is necessary for one or several components—publishers—to send the message to one or several components—addressees (subscribers). The given model is based on the message topic concept: Publishers send messages in a topic, and all subscribers of the given topic receive these messages.
The pub-sub model seems to be more "elegant," but many pub-sub systems do not guarantee delivery of messages in the order in which they have been sent (as opposed to point-to-point, where the queue realizes the FIFO (first-in/first-out) principle). Therefore, in the case of pub-sub, models should be avoided whenever possible in situations when the order of following the messages is important (or it will be necessary to use headers and properties sections of messages for synchronization).
Java Message Service (JMS) is a Java API for working with Message-Oriented Middleware, allowing your applications to create, send, accept, and read messages. The given set is located in a javax.jms package in a tree of J2EE packages. JMS is implemented in many MOM-products, among which iPlanet Message Queue, IBM MQSeries, Progress Software SonicMQ, BEA WebLogic Server, Prism Technologies OpenFusion, and so forth are best known. A freeware implementation also exists.
JMS supports both "basic" models of message exchange. However, the specification does not require the manufacturer to implement both models, although the majority of JMS products implement the point-to-point and pub-sub models.
The main parts of JMS applications are:
- ConnectionFactory and Destination
ConnectionFactory is the object responsible for creating JMS Connection. Each such ConnectionFactory is a copy of QueueConnectionFactory or TopicConnectionFactory. The MOM manager creates the given object and connects it with the JNDI tree so the JMS client can get access to ConnectionFactory using a standard JNDI lookup. In the case of a point-to-point model, it is using javax.jms.QueueConnectionFactory; in the case of pub-sub models, javax.jms.TopicConnectionFactory.
Destination—it's a queue or topic, depending on which model we are using: javax.jms.Queue or javax.jms.Topic.
Connection—it can be an open TCP/IP between the client and supplier service. It can be used to create one or few sessions. Before your application can receive messages, you need to call the start() method. To pause sending messages, you need to call stop().
Session—the object created with help of JMS Connection and used by clients to send and receive messages.
MessageProducer—the object created by the session and used to send messages in Destination.
MessageConsumer—the object created by the session and used to receive messages. To synchronously receive the message, the receive() method is used. For asynchronous, MessageListener is used with only one method—onMessage(). In this method, actions that should be executed after the arrival of the message are defined.
Message—the message itself. The JMS message will consist of three parts:
- Properties (not necessary)
- Body (not necessary)
A more detailed explanation is beyond the scope of this article; you can specify these details with the help of official documentation.