Introduction to JMS

JMS Messaging

The Java Message Service (JMS) is a Java API that allows applications to communicate with each other using a common set of interfaces. The JMS API provides messaging interfaces, but not the implementations.

A JMS provider, such as Software AG Universal Messaging or webMethods Broker, is a messaging system that supports the JMS message interfaces and provides administrative and control features. It supports the routing and delivery of JMS messages.

JMS clients are the programs or components, written in Java, that produce and consume messages.

Note: webMethods Broker is deprecated.

Messaging Styles

A messaging style refers to how messages are produced and consumed. JMS supports the publish-subscribe (pub-sub) and point-to-point (PTP) messaging styles.

Point-to-point (PTP) Messaging

In point-to-point (PTP) messaging, message producers and consumers are known as senders and receivers.

The central concept in PTP messaging is a destination called a queue. A queue represents a single receiver. Message senders submit messages to a specific queue and another client receives the messages from the queue.

In the PTP model, a queue may receive messages from many different senders and may deliver messages to multiple receivers; however, each message is delivered to only one receiver.

Publish-Subscribe Messaging

In publish-subscribe messaging, message producers and consumers are known as publishers and subscribers.

The central concept in the publish-subscribe messaging is a destination called a topic. Message publishers send messages of specified topics. Clients that want to receive that type of message subscribe to the topic.

The publishers and subscribers never communicate with each other directly. Instead, they communicate by exchanging messages through a JMS provider.

Publishers and subscribers have a timing dependency. Clients that subscribe to a topic can consume only messages published after the client has created a subscription. In addition, the subscriber must continue to be active to consume messages.

The messaging APIs relax this dependency by making a distinction between durable subscriptions and non-durable subscriptions.

Durable Subscriptions

Durable subscriptions allow subscribers to receive all the messages published on a topic, including those published while the subscriber is inactive. When the subscribing applications are not running, the messaging provider holds the messages in nonvolatile storage. It retains the messages until one of the following occurs:
  • The subscribing application becomes active, identifies itself to the provider, and sends an acknowledgment of receipt of the message.
  • The expiration time for the messages is reached.

Non-durable Subscriptions

Non-durable subscriptions allow subscribers to receive messages on their chosen topic only if the messages are published while the subscriber is active. You generally use this type of subscription for any kind of data that is time sensitive, such as financial information.

JMS API Programming Model

The following section summarizes the most important components of the JMS API.

The building blocks of a JMS application consist of the following:
  • Administered objects (connection factories and destinations)
  • Connections
  • Sessions
  • Message producers
  • Message consumers
  • Messages

Administered Objects

Administered objects are pre-configured objects that an administrator creates for use with JMS client programs. Administered objects serve as the bridge between the client code and the JMS provider.

By design, the messaging APIs separate the task of configuring administered objects from the client code. This architecture maximizes portability: the provider-specific work is delegated to the administrator rather than to the client code. However, the implementation must supply its own set of administrative tools to configure the administered objects.

JMS administered objects are stored in a standardized namespace called the Java Naming and Directory Interface (JNDI). JNDI is a Java API that provides naming and directory functionality to Java applications. JNDI provides a way to store and retrieve objects by a user supplied name.

Types of Administered Objects

There are two types of administered objects: connection factories and destinations.

Connection Factories

A connection factory is the object a client uses to create a connection with a JMS provider. It encapsulates the set of configuration parameters that a JMS administrator defines for a connection.

The type of connection factory determines whether a connection is made to a topic (in a publish-subscribe application), a connection is make to a queue (in a point-to-point application), or a connection can be made to both (generic connection). The connection factory type also determines whether messages are managed like elements in a distributed transaction in the client application.

You use XA-based connection factories in JMS applications managed by an application server, in the context of a distributed transaction.

Destinations
Destinations are the objects that a client uses to specify the target of messages it produces and the source of messages it consumes. These objects specify the identity of a destination to a JMS API method. Four types of destinations exist; only the first two (queues and topics) are administered objects.
  • Queue. An object that covers a provider-specific queue name. This object is how a client specifies the identity of a queue to JMS methods.
  • Topic. An object that covers a provider-specific topic name. This object is how a client specifies the identity of a topic to JMS methods.
  • Temporary Queue. A queue object created for the duration of a particular connection (or QueueConnection). It can only be consumed by the connection from which it was created.
  • Temporary Topic. A topic object that is created for the duration of a particular connection (or TopicConnection). It can only be consumed by the connection from which it was created.

Connections

A connection object is an active connection from a client to its JMS provider. In JMS, connections support concurrent use. A connection serves the following purposes:
  • A connection encapsulates an open connection with a JMS provider. It typically represents an open TCP/IP socket between a client and the service provider software.
  • The creation of a connection object is the point where client authentication takes place.
  • A connection object can specify a unique client identifier.
  • A connection object supports a user-supplied ExceptionListener object.

A connection should always be closed when it is no longer needed.

Sessions

A session object is a single-threaded context for producing and consuming messages. If a client uses different threads for different paths of message execution, then a session must be created for each of the threads.

A session is used to create message producers, message consumers, temporary topics, and temporary queues; it also supplies provider-optimized message factories.

In JMS, a session provides the context for grouping a set of send and receive messages into a transactional unit.

Message Producer

A message producer is an object that a session creates to send messages to a destination (a topic or a queue).

Message Consumer

A message consumer is an object that a session creates to receive messages sent to a destination. A message consumer allows a client to register interest in a destination, which manages the delivery of messages to the registered consumers of that destination.

Message Selector

A client may want to receive subsets of messages. A message selector allows a client to filter the messages it wants to receive by use of a SQL92 string expression in the message header. That expression is applied to properties in the message header (not to the message body content) containing the value to be filtered.

If the SQL expression evaluates to true, the message is sent to the client; if the SQL expression evaluates to false, it does not send the message.

Messages

Messages are objects that communicate information between client applications. Following are descriptions of several key concepts related to JMS messages.

Message Structure

Messages are composed of the following parts:
  • Header. All messages support the same set of header fields. Header fields contain predefined values that allow clients and providers to identify and route messages. Each of the fields supports its own set and get methods for managing data. Some fields are set automatically by the send and publish methods, whereas others must be set by the client.

    Examples of header fields include:

    • JMSDestination, which holds a destination object representing the destination to which the message is to be sent.
    • JMSMessageID, which holds a unique message identifier value and is set automatically.
    • JMSCorrelationID, which is used to link a reply message with its requesting message. This value is set by the client application.
    • JMSReplyTo, which is set by the client and takes as a value a Destination object representing where the reply is being sent. If no reply is being sent, this field is set to null.
  • Properties (optional). Properties are used to add optional fields to the message header. Several types of message property fields exist:
    • Application-specific properties are typically used to hold message selector values. Message selectors are used to filter and route messages.
    • Standard properties. The API provides some predefined property names that a provider may support. Support for the JMSXGroupID and JMSXGroupSeq is required; however, support for all other standard properties is optional.
    • Provider-specific properties are unique to the messaging provider and typically refer to internal values.
  • Body (optional). The JMS standard defines various types of message body formats that are compatible with most messaging styles. Each form is defined by a message interface.
    • StreamMessage. A message whose body contains a stream of Java primitive values. It is filled and read sequentially.
    • MapMessage. A message whose body contains a set of name-value pairs where names are Strings and values are Java primitive types. The entries can be accessed sequentially by enumerator or randomly by name. The order of the entries is undefined.
    • TextMessage. A message whose body contains a java.lang.String.
    • ObjectMessage. A message that contains a Serializable Java object.
    • BytesMessage. A message that contains a stream of uninterpreted bytes. This message type is for literally encoding a body to match an existing message format. In many cases, it will be possible to use one of the other, self-defining, message types instead.

Both StreamMessage and MapMessage support the same set of primitive data types. Conversions from one data type to another are possible.

Message Acknowledgment

A message is not considered to be successfully consumed until it is acknowledged. Depending on the session acknowledgment mode, the messaging provider may send a message more than once to the same destination. Several message acknowledgment constants exist.

Value Description
AUTO_ACKNOWLEDGE Automatically acknowledges the successful receipt of a message.
CLIENT_ACKNOWLEDGE Acknowledges the receipt of a message when the client calls the message’s acknowledge() method.
DUPS_OK_ACKNOWLEDGE Instructs the session to automatically, lazily acknowledge the receipt of messages, which reduces system overhead but may result in duplicate messages being sent.