Today we are going to explore the Java Message Service (JMS) architecture and its components. In the previous series we have learnt about the JMS, messaging and various types of messaging model. You can refer to the last article here: “Introduction to JMS“.
The JMS is a specification and not an implementation. The JMS specification provides the guidelines of what to implement and how the Java based applications can interact with each other/non-Java based clients to create, send, receive and read the messages. It is the vendors who adheres to these specifications and defines how these messaging system needs to be implemented. They use the JMS API javax.jms.
We will take help of the following diagram to describe the whole concept.
This diagram shows the various main elements of the JMS architecture. The JMS service providers implement the JMS interface on top of their messaging services. Nowadays most of the Application servers provide inbuilt implementation of the JMS Messaging services e.g. Weblogic, JBoss etc. These vendors can provide additional features, enhancements, services on top of the defined JMS specifications.
There are four elements of the JMS architecture which are explained the below table:
Vendors implement the JMS specification by supplying a JMS provider consisting of libraries that implement the JMS interfaces. This provides the core functionality for routing and delivering messages between clients, manages the administered objects and also manage, monitor, and tune the messaging service. The JMS provider ensures asynchronous communication, supports reliable message delivery and transaction control.
The JMS clients act as a message sender or receiver. The JMS clients make API calls to send message to the queue/ topic which are managed by the JMS providers. The message receivers on the other hand receive messages from these queue/ topic.
The messages are objects which are used to communicate information between the clients. The JMS messages has 3 parts: (i) Header (ii) Properties (iii) Body
Administered objects are for client use, but are created by an administrator. There are two main administered objects—destination and connection factories. These objects are managed by the JMS provider. The destinations are nothing but references to the physical implementation of Queues or Topics.
The architecture diagram highlights an app server implementing the JMS specifications and messaging services. These App servers also have their own JNDI implementations.
- The administrator creates the physical destination (Queues in case of PTP or Topic in case of Pub/Sub model) in the JMS providers from the JMS admin console. This is actually a physical location in the server.
- In the JNDI namespace the administrator creates two administered objects i) Destination ii) Connection factories. The administrator configures/ binds the destination administered objects with the corresponding physical location on the JMS provider. In this example we are trying to map the physical location of the Queue1 to an object reference Q1, Queue2 to Q2.The connection factories administered objects are created in a similar way. The administrator creates/ configures a connection factory administered object through the admin console.
- The message sender/ producer (JMS Client) uses the connection factory to create a new connection with the provider. It then uses a standard JNDI call to look up for the administered object queue (in this example it is referred in the JNDI namespace as Q1) for sending messages.
- At this stage the message sender establishes a logical connection between the JMS client and the Queue in the JMS provider (in this example JMS Client A secures a logical connection with Queue 1) and is now ready for sending message. Once the background has been set the Sender sends the message to the physical destination (Queue 1).
- The message consumer uses a JNDI call to look up the destination administered object that points to the corresponding physical destination from which it expects to get messages.
- In this case as well the message consumer/receiver gets the message from the physical destination (Q1).
JMS Message Structure:
- Header:A header must be present in every JMS message, and it is assigned automatically. Most of the values in the header are set by the JMS provider when the message is put to a JMS destination.A header contains values used by both clients and providers to identify and route messages. The data elements of each header comprise name-value pairs and they can be any of the Java following types: Boolean, byte, short, char, long, int, float, double, string or byte[ ].
- Properties:This field is an optional entity and includes several vendor specific or application specific information.
- Message Body:A JMS message body contains the content being delivered from a producer to a consumer. There five types of message bodies: Stream, Map, Text, Object, Bytes and XML.
The JMS messages are consumed by the clients / receivers from the destination (either queue/ topic) in the following ways:
- Synchronous mode – In this case the receiver fetches the message from the destination through receive() method of the javax.jms package. This method call blocks indefinitely until a message is produced or until this message receiver is closed. The receiver does not perform any other transactions during this time. However we can also specify a timeout value through receive(timeout) method which means receiver does not perform any other transactions until a message arrives or receiver is closed within the timeout value. If there is no message received till the timeout value then the timeout expires and receiver is released from the block state. A timeout of zero never expires, and the call blocks indefinitely i.e. receive(0) is similar to receive().
- Asynchronous mode – In this case the JMS client/ subscriber uses a messageListener object to receive messages asynchronously delivered messages. Whenever a message arrives at its destination, the JMS provider/ message server delivers the message to the subscriber by using the onMessage() method. The client will not be blocked while waiting for the message.
In the next series we will discuss about the JMS implementation, connection factories and sessions. Please watch this space. I am looking forward for your comments and feedback on the above article.
JMS: Java Message Service
JNDI: Java Naming and Directory Interface
MOM: Message Oriented Middleware