Messaging is a means of data exchange between software applications or components. The sending application sends messages to a destination and the recipient application retrieves the messages from the destination.
Unlike most other means of communication, messaging is loosely coupled. The sending application sends messages to a destination and does not know anything about the receiving application. The receiving application retrieves the message from the destination and does not know anything about the sending application.
The sender and receiver need not be available at the same time to successfully exchange messages. For example, the sending application can continue to send messages to the destination even when the receiving application is not available. When the receiving application becomes available again, it can retrieve the messages from the destination.
Java Message Service is a Java API that enables software applications or components written in Java programming language to communicate with messaging implementations.
JMS makes it easier for a programmer to develop messaging applications by providing high level interfaces and components to create, send, receive and read messages.
JMS API provides a standard for JMS product implementors ensuring the portability of JMS applications across different JMS providers.
Loosely Coupled - Messaging is loosely coupled. The sending application sends messages to a destination and does not know anything about the receiving application. The receiving application retrieves messages from the destination and does not know anything about the sending application.
Asynchronous - Messaging is asynchronous. The sending application and receiving application need not be available at the same time. The sending application can send the message and continue processing its other tasks. The receiving application can retrieve the messages at a later time.
Reliable - Any messaging product that implements JMS API ensures that messages are delivered once and only once. Lower levels of reliability can be set if it is ok for an application to either miss messages or receive duplicate messages.
JMS supports two messaging styles - point-to-point and publish-subscribe.
Point-to-Point - In point-to-point messaging, the sending application sends messages to a destination from which only one receiving application can consume the messages. The destination to which messages are send to is known as a queue.
Publish-Subscribe - In publish-subscribe messaging the sending application sends messages to a destination from which messages can be consumed by multiple different receiving applications. The destination to which publish-subscribe style messages are send to is known as a topic.
Queues are the destination in point-to-point messaging. Sending application sends messages to the queue and receiving application retrieves messages from the queue. Only a single receiving application can retrieve messages from the queue.
Topics are destinations in publish-subscribe messaging. Sending application sends messages to the topic and receiving application retrieves messages from the topic. Multiple receiving applications can subscribe to the same topic. Hence the same message for the topic can be send to multiple receiving application.
Following are the key components of a JMS application.
Connection Factory - Connection factory is an object provided in the JMS API that is used to create a connection to the destination queue or topic. A connection factory is an instance of ConnectionFactory, QueueConnectionFactory or TopicConnectionFactory interfaces provided by the JMS API. Connection factory is an administered object in a JMS API implementor such as a Java EE server.
Connection - A connection represents a virtual connection to the JMS provider. Connection is created from the connection factory object through a JMSContext object.
Session - A session is s single threaded context for producing and consuming messages. Similar to a connection, session is created from connection factory by creating a JMSContext object.
JMSContext object - A JMSContext object encapsulates a connection and a session and is created from the connection factory. JMSContext is used to create message producers, message consumers and messages.
Message Producer - A message producer is an object used for sending messages to a destination. Message producer implements the JMSProducer interface provided the the JMS API. A message producer is created from the JMS context object.
Message Consumers - A message consumer is an object used from consuming messages from a destination. A message consumer implements the JMSConsumer interface provided by JMS API. A message consumer is created from the JMS context object.
Message - Message contains the data that the sending application sends to a destination or the data that a receiving application retrieves from.
JMS connection factory is an administered object and is injected into the JMS application code using its JNDI name.
JMS destinations i.e. queues and topics, are administered object and are injected into the JMS application code using its JNDI name.
JMSContext object encapsulates the connection and session required to connect to a JMS provider
JMSContext is created from the connection factory by calling its createContext() method.
JMSContext object is used to create message producer by calling its createProducer(). JMSContext object is used to create message consumer by calling its createConsumer() method.
JMSProducer object is used to send messages to a destination. JMSProducer object is created from a JMSContext object by calling its createProducer() method.
JMSConsumer object is used to retrieve messages from a destination. JMSConsumer object is created from a JMSContext object by calling its createConsumer() method.
A message listener acts an asynchronous event handler for consuming messages. A message listener implements MessageListener interface and overwrites its onMessage() method.
The message listener is registered to a message consumer by calling its setMessageListener() method.
Once a message listener is registered to a message consumer, the JMS provider automatically sends any messages put on the destination to the listeners onMessage() method.
A JMS message has three different parts - Header, Properties and Body.
Header - A JMS message header contains a number of pre-defined header fields that are used to identify and route messages. Some examples of header fields are destination, delivery mode, delivery time, priority and expiration time of the message.
Properties - In addition to the fields defined in the header, you can create and set additional fields if needed in the properties section of the message.
Body - JMS message body contains the actual data of the message that is send to the destination by the sender and retrieved by the receiver. The message body can contain messages of six different types - text, map, bytes, stream, object and message which is used when no data is required to be send.
JMS API supports six different types of messages.
Text Message - Message containing text of type java.lang.String
Map Message - Message containg key-value pairs. Key is of type java.lang.String and value is any of the primitive data types defined in Java programming language.
Bytes Message - Message containing a stream of bytes
Stream Message - Message containing a stream of primitive data types.
Object Message - Message containing a serializable Java object.
Message - Does not contain a message body. Used when only header and properties are required ti be send.
The root class for all checked exceptions in JMS API is JMSException
The root cause of all unchecked exceptions in JMS API is JMSRuntimeException.
A message can be set to be persistent or non-persistent by calling the setDeliveryMode() method on the JMSProducer interface and setting the mode to be persistent or non-persistent.
Priority of a message can be set by calling the setPriority() method on the JMSProducer interface and setting the priority value. The priority value can range from 0 to 9, 0 being the lowest and 9 the highest.
A message can be set to expire after a certain period of time. You can set the expiration time by calling the setTimeToLive() method on the JMSProducer interface and setting the expiration time.