The JMS model

The JMS model defines a set of interfaces that Java applications can use to perform messaging operations. IBM® MQ classes for JMS, as a JMS provider, defines how JMS objects are related to IBM MQ concepts. The JMS specification expects certain JMS objects to be administered objects. The latest version, JMS 2.0 introduces a simplified API, while also retaining the classic API, from version 1.1.

The JMS specification and the javax.jms package define a set of interfaces that Java applications can use to perform messaging operations.

Simplified API

JMS 2.0 introduces the simplified API, while also retaining the domain specific and domain independent interfaces from JMS 1.1. The simplified API reduces the number of objects that are needed to send and receive messages and consists of the following interfaces:
ConnectionFactory
A ConnectionFactory is an administered object that is used by a JMS client to create a Connection. This interface is also used in the classic API.
JMSContext
This object combines the Connection and Session objects of the classic API. JMSContext objects can be created from other JMSContext objects, with the underlying connection being duplicated.
JMSProducer
A JMSProducer is created by a JMSContext and is used to send messages to a queue or topic. The JMSProducer object causes the creation of objects that are required to send the message.
JMSConsumer
A JMSConsumer is created by a JMSContext and is used to receive messages from a topic or a queue.
The simplified API has a number of effects:
  • The JMSContext object always automatically starts the underlying connection.
  • JMSProducers and JMSConsumers can now work directly with message bodies, without having to get the whole message object, by using the Message's getBody method.
  • Message properties can be set on the JMSProducer object, using method chaining, before sending a 'body', a messages content. The JMSProducer will handle the creation of all objects that are needed to send the message. Using JMS 2.0, properties can be set, and a message sent as follows:
    
    context.createProducer().
    setProperty("foo", "bar").
    setTimeToLive(10000).
    setDeliveryMode(NON_PERSISTENT).
    setDisableMessageTimestamp(true).
    send(dataQueue, body);
    

JMS 2.0 also introduces shared subscriptions where messages can be shared between multiple consumers. All JMS 1.1 subscriptions are treated as unshared subscriptions.

Classic API

The following list summarizes the main JMS interfaces of the classic API:
Destination
A destination is where an application sends messages, or it is a source from which an application receives messages, or both.
ConnectionFactory
A ConnectionFactory object encapsulates a set of configuration properties for a connection. An application uses a connection factory to create a connection.
Connection
A Connection object encapsulates an application's active connection to a messaging server. An application uses a connection to create sessions.
Session
A session is a single threaded context for sending and receiving messages. An application uses a session to create messages, message producers, and message consumers. A session is either transacted or not transacted.
Message
A Message object encapsulates a message that an application sends or receives.
MessageProducer
An application uses a message producer to send messages to a destination.
MessageConsumer
An application uses a message consumer to receive messages sent to a destination.
Figure 1 shows these objects and their relationships.
Figure 1. JMS objects and their relationships
The diagram shows the main JMS interfaces: ConnectionFactory, Connection, Session, MessageProducer, MessageConsumer, Message, and Destination. An application uses a connection factory to create a connection, and uses a connection to create sessions. The application can then use a session to create messages, message producers, and message consumers. The application uses a message producer to send messages to a destination, and uses a message consumer to receive messages sent to a destination.

A Destination, ConnectionFactory, or Connection object can be used concurrently by different threads of a multithreaded application, but a Session, MessageProducer, or MessageConsumer object cannot be used concurrently by different threads. The simplest way of ensuring that a Session, MessageProducer, or MessageConsumer object is not used concurrently is to create a separate Session object for each thread.

JMS support two styles of messaging:
  • Point-to-point messaging
  • Publish/subscribe messaging
These styles of messaging are also referred to as messaging domains, and you can combine both styles of messaging in an application. In the point-to-point domain, a destination is a queue and, in the publish/subscribe domain, a destination is a topic.
With versions of JMS before JMS 1.1, programming for the point-to-point domain uses one set of interfaces and methods, and programming for the publish/subscribe domain uses another set. The two sets are similar, but separate. As of JMS 1.1, you can use a common set of interfaces and methods that support both messaging domains. The common interfaces provide a domain independent view of each messaging domain. Table 1 lists the JMS domain independent interfaces and their corresponding domain specific interfaces.
Table 1. The JMS domain independent and domain specific interfaces
Domain independent interfaces Domain specific interfaces for the point-to-point domain Domain specific interfaces for the publish/subscribe domain
ConnectionFactory QueueConnectionFactory TopicConnectionFactory
Connection QueueConnection TopicConnection
Destination Queue Topic
Session QueueSession TopicSession
MessageProducer QueueSender TopicPublisher
MessageConsumer
QueueReceiver
QueueBrowser
TopicSubscriber

JMS 2.0 retains all the domain specific interfaces, and so existing applications can still use these interfaces. For new applications, however, consider using the domain independent interfaces of 1.1 or the simplified API of 2.0.

In IBM MQ classes for JMS, JMS objects are related to IBM MQ concepts in the following ways:
  • A Connection object has properties that are derived from the properties of the connection factory that was used to create the connection. These properties control how an application connects to a queue manager. Examples of these properties are the name of the queue manager and, for an application that connects to the queue manager in client mode, the host name or IP address of the system on which the queue manager is running.
  • A Session object encapsulates an IBM MQ connection handle, which therefore defines the transactional scope of the session.
  • A MessageProducer object and a MessageConsumer object each encapsulates an IBM MQ object handle.

When using IBM MQ classes for JMS, all the normal rules of IBM MQ apply. Note, in particular, that an application can send a message to a remote queue but it can receive a message only from a queue that is owned by the queue manager to which the application is connected.

The JMS specification expects ConnectionFactory and Destination objects to be administered objects. An administrator creates and maintains administered objects in a central repository, and a JMS application retrieves these objects using the Java Naming and Directory Interface (JNDI).

In IBM MQ classes for JMS, the implementation of the Destination interface is an abstract superclass of Queue and Topic, and so an instance of Destination is either a Queue object or a Topic object. The domain independent interfaces treat a queue or a topic as a destination. The messaging domain for a MessageProducer or MessageConsumer object is determined by whether the destination is a queue or a topic.

In IBM MQ classes for JMS therefore, objects of the following types can be administered objects:
  • ConnectionFactory
  • QueueConnectionFactory
  • TopicConnectionFactory
  • Queue
  • Topic
  • XAConnectionFactory
  • XAQueueConnectionFactory
  • XATopicConnectionFactory