. . .
try (JMSContext context = connectionFactory.createContext();){
// use context in this try block
// it will be closed when try block completes
} catch (JMSException e){
// exception handling
}
. . .
The JMS Simplified API |
Previous | Next | Contents |
This chapter describes the JMS Simplified API defined by the Java Message Service (JMS) 2.0 specification and implemented in the Message Queue Java API.
Note
|
The JMS Classic API offers the same functionality and is described in The JMS Classic API. For detailed reference information, see the JavaDoc documentation for each individual class. |
The topics covered include the following:
The Simplified API provides the same basic functionality as the Classic API but requires fewer interfaces and is simpler to use.
The main interfaces are:
ConnectionFactory
—An administered object used by a client to create
a Connection
. This interface is also used by the Classic API.
JMSContext
—An active connection to a JMS provider and a
single-threaded context used to send or receive messages.
JMSProducer
—An object created by a JMSContext
to send messages to
a queue or topic.
JMSConsumer
—An object created by a JMSContext
to receive messages
sent to a.queue or topic
In the Simplified API, the JMSContext
combines the behaviors of the
Classic API Connection
and Session
objects. A Connection
continues
to represent a physical link to a JMS server. A Session
continues to
represent a single-threaded context for sending or receiving messages.
Figure 3-1 shows an overview of the Simplified API.
]"]
For more information, see "The Java Message Service specification, version 2.0", available from http://jcp.org/en/jsr/detail?id=343.
Objects from interfaces that extend the java.lang.Autocloseable
and
use a try-with-resources
statement do not need to explicitly call
close()
when these objects are no longer required.
The following interfaces extend the java.lang.Autocloseable
interface:
JMSContext
JMSConsumer
QueueBrowser
For example:
. . .
try (JMSContext context = connectionFactory.createContext();){
// use context in this try block
// it will be closed when try block completes
} catch (JMSException e){
// exception handling
}
. . .
You can use the getBody
method to provide a convenient way to obtain
the body from a newly-received Message
object. Use getBody
to:
Return the body of a TextMessage
, MapMessage
, or BytesMessage
as
a String
, Map
, or byte[]
without the need to cast the Message
first to the appropriate subtype.
Return the body of an ObjectMessage
without the need to cast the
Message
to ObjectMessage
, extract the body as a Serializable
, and
cast it to the specified type.
The isBodyAssignableTo
method can be used to determine whether a
subsequent call to getBody
would be able to return the body of a
particular Message
object as a particular type.
This section provides the basic steps required to create a JMS client using the Simplified API.
Example 3-1 Sending a Message using the Simplified API
public void sendMessageNew(String body) throws NamingException{
InitialContext initialContext = getInitialContext();
ConnectionFactory connectionFactory = (ConnectionFactory)
initialContext.lookup("jms/connectionFactory");
Queue inboundQueue = (Queue) initialContext.lookup("jms/inboundQueue");
try (JMSContext context = connectionFactory.createContext();){
context.createProducer().send(inboundQueue,body);
}
}
. . .
See "Java Message Service Examples" in The Java EE 7 Tutorial for additional information.
In the simplified API a connection and a session are represented by a
single JMSContext
object. When a JMSContext
is created the
underlying session is created automatically.
Since a JMSContext
incorporates a session, it is subject to the same
threading restrictions as a session. This means that it may only be used
by one thread at a time (single-threaded).
The JMSContext
method createContext
does not use its underlying
session and is not subject to the single-threading restriction.
The close
method on JMSContext
or JMSConsumer
is not
single-threaded since closing a session or consumer from another thread
is permitted.
By default, when createConsumer
or createDurableConsumer
is used
to create a JMSConsumer
, the connection is automatically started. If
setMessageListener
is called to configure the asynchronous delivery of
messages, the JMSContext
's session immediately becomes dedicated to
the thread of control that delivers messages to the listener. The
application must not subsequently call methods on the JMSContext
from
another thread of control. However, this restriction does not apply to
applications which call setMessageListener
to set a second or
subsequent message listener. The JMS provider is responsible for
ensuring that a second message listener may be safely configured even if
the underlying connection has been started.
See "The JMS API Programming Model" in The Java EE 7 Tutorial for additional information.
All Message Queue messages travel from a message producer to a message consumer by way of a destination on a message broker. Message delivery is thus a two-stage process: the message is first delivered from the producer to the destination and later from the destination to the consumer. Physical destinations on the broker are created administratively by a Message Queue administrator, using the administration tools described in "Configuring and Managing Physical Destinations" in Open Message Queue Administration Guide. The broker provides routing and delivery services for messages sent to such a destination.
Message Queue supports two types of destination, depending on the messaging domain being used:
Queues (point-to-point domain)
Topics (publish/subscribe domain)
These two types of destination are represented by the Message Queue
classes Queue
and Topic
, respectively. These, in turn, are both
subclasses of the generic class Destination
. A client program that
uses the Destination
superclass can thus handle both queue and topic
destinations indiscriminately.
See "The JMS API Programming Model" in The Java EE 7 Tutorial for additional information.
This section describes how to use the Message Queue Java API to compose, send, receive, and process messages. See "The JMS API Programming Model" in The Java EE 7 Tutorial for additional information.
The following section provides information on message structure:
A header containing identifying and routing information.
Optional properties that can be used to convey additional identifying information beyond that contained in the header
A body containing the actual content of the message.
For more information, see Message Structure.
Every message must have a header containing identifying and routing information. The header consists of a set of standard fields, which are defined in the Java Message Service Specification and summarized in Table 3-1. Some of these are set automatically by Message Queue in the course of producing and delivering a message, some depend on settings specified when a message producer sends a message, and others are set by the client on a message-by-message basis.
Table 3-1 Message Header Fields
Name | Description |
---|---|
|
Message identifier |
|
Destination to which message is sent |
|
Destination to which to reply |
|
Link to related message |
|
Delivery mode (persistent or nonpersistent) |
|
The earliest time a provider may make a message visible on a target destination and available for delivery to consumers. |
|
Priority level |
|
Time of transmission |
|
Expiration time |
|
Message type |
|
Has message been delivered before? |
The JMS Message
interface defines the following methods for setting
the corresponding value of each header field. Table 3-2
lists all of the available header specification methods for the JMS
Message
interface.
Table 3-2 JMS 2.0 Message Header Methods for the Message Interface
Name | Description |
---|---|
|
Set destination |
|
Set reply destination |
|
Set correlation identifier from string |
|
Set correlation identifier from byte array |
|
Set message type |
The JMS Producer
interface defines the following methods for setting
the corresponding value of each header field. Table 3-3
lists all of the available header specification methods.
Table 3-3 JMS 2.0 Message Header Methods for the Producer Interface
Name | Description |
---|---|
|
Set message identifier |
|
Set delivery mode |
|
Set priority level |
|
Set time stamp |
|
Set expiration time |
|
Set redelivered flag |
|
Set the delivery time for a message |
See the "Java Message Service specification, version 2.0", available from http://jcp.org/en/jsr/detail?id=343 for a more detailed discussion of all message header fields.
The JMS specification defines certain standard properties, listed in
Table 3-4. By convention, the names of all such standard
properties begin with the letters JMSX
; names of this form are
reserved and must not be used by a client application for its own custom
message properties. These properties are not enabled by default, an
application must set the name/value pairs it requires on the appropriate
connection factory.
The JMS 2.0 specification requires that JMS producers set the
JMSXDeliveryCount
. This property was not supported prior to MQ 5.0.
Table 3-4 Standard JMS 2.0 Message Properties
Name | Type | Required? | Set by | Description |
---|---|---|---|---|
|
|
Optional |
Provider on Send |
Identity of user sending message |
|
|
Optional |
Provider on Send |
Identity of application sending message |
|
|
Required |
Provider on Receive |
Number of delivery attempts |
|
|
Optional |
Client |
Identity of message group to which this message belongs |
|
|
Optional |
Client |
Sequence number within message group |
|
|
Optional |
Provider on Send |
Identifier of transaction within which message was produced |
|
|
Optional |
Provider on Receive |
Identifier of transaction within which message was consumed |
|
|
Optional |
Provider on Receive |
Time message delivered to consumer |
|
|
Optional |
Provider |
Message state (waiting, ready, expired, or retained) |
In order to send messages to a message broker, you must create a
JMSProducer
object using the createProducer()
method on
JMSContext
. For example:
try (JMSContext context = connectionFactory.createContext();){context.createProducer().send(inboundQueue,body)
}
The JMS 2.0 specification allows a client to specify a delivery delay value, in milliseconds, for each message it sends. This value is used to determine a messages’s delivery time which is calculated by adding the delivery delay value specified on the send to the time the message was sent. See Message Headers.
Table 3-5 shows the methods defined in the JMSProducer
interface.
Table 3-5 JMSProducer Methods
Name | Description |
---|---|
|
Get default destination |
|
Set default delivery mode |
|
Get default delivery mode |
|
Get delivery delay value in milliseconds |
|
Set delivery delay value in milliseconds |
|
Set default priority level |
|
Get default priority level |
|
Set default message lifetime |
|
Get default message lifetime |
|
Set message identifier disable flag |
|
Get message identifier disable flag |
|
Set time stamp disable flag |
|
Get time stamp disable flag |
|
Send message |
|
Close message producer |
In the Simplified API, a JMS provider sends a message asynchronously by
calling setAsync(CompletionListener completionListener)
on the
JMSProducer
prior to calling one of the following send
methods:
send(Destination destination, Message message)
send(Destination destination, String body)
send(Destination destination, Map<String,Object> body)
send(Destination destination, byte[] body)
send(Destination destination, Serializable body)
send(Destination destination, String body)
Note
|
These |
For more information on how to convert common synchronous send design patterns to use asynchronous sends, see Asynchronous send.
This section provides information on new behaviors and two new subscription types for clients to use when consuming messages.
A shared non-durable subscription is used by a client that needs to be able to share the work of receiving messages from a non-durable topic subscription across multiple consumers. Each message from the subscription is delivered to only one of the consumers that may exist on that subscription.
Shared non-durable subscriptions are created and a consumer crated on the subscription using one of the following:
Classic API: One of the createSharedConsumer
methods on Session
which return a MessageConsumer
object.
Simplified API: One of the createSharedConsumer
methods on
JMSContext
which returns a JMSContext
object.
A shared non-durable subscription exists only as long as there is an
active consumer on the subscription. It is identified by name and an
optional client identifier (clientId
). If the client identifier was
set when the subscription was created, any client that creates a
consumer on that shared non-durable subscription must use the same
client identifier. This type of subscription is not persisted and is
deleted, along with any undelivered messages, when the last consumer on
the subscription is deleted. The noLocal
parameter is not supported
for shared non-durable subscriptions.
A shared durable subscription is used by an application that needs to share the work of receiving all the messaged published on a topic, including messages published when no consumers are associated with the subscription. Each message from the subscription is delivered to only one of the consumers that may exist on that subscription. For this subscription type, the JMS provider ensures all the messages from the topic’s publishers:
Are Delivered and acknowledged or
Have expired
Shared durable subscriptions are created and a consumer crated on the subscription using one of the following:
Classic API: One of the createSharedDurableConsumer
methods on
Session
which return a MessageConsumer
object.
Simplified API: One of the createSharedDurableConsumer
methods on
JMSContext
which returns a JMSContext
object.
A shared durable e subscription persists and accumulates messages until
it is explicitly deleted using the unsubscribe
method on either
Session
or JMSContext
. You cannot delete a durable subscription with
an active consumer or while a message is received from the subscription
is part of a transaction. It is identified by name and an optional
client identifier (clientId
). If the client identifier was set when
the subscription was created, any client that creates a consumer on that
shared non-durable subscription must use the same client identifier. The
noLocal
parameter is not supported for shared durable subscriptions.
An application using the Classic API to consume messages needs to call
the connection’s start
method to start delivery of incoming messages.
It may temporarily suspend delivery by calling stop
, after which a
call to start
will restart delivery.
The Simplified API provides corresponding start
and stop
methods on
JMSContext
. The start
method is be called automatically when
createConsumer
or createDurableConsumer
are called on the
JMSContext
object. There is no need for the application to call
start
when the consumer is first established. An application may
temporarily suspend delivery by calling stop
, after which a call to
start
will restart delivery.
In some situations, an application using the Simplified API may need a
connection to remain in stopped mode while setup is being completed and
not commence message delivery until the start
method is explicitly
called. You can configure this behavior by calling setAutoStart(false)
on the JMSContext
prior to calling createConsumer
or
createDurableConsumer
.
Processing a message after you have received it may entail examining its header fields, properties, and body.
The standard JMS message header fields are described in
Table 3-4. Table 3-6 shows the methods
provided by the JMS Message
interface for retrieving the values of
these fields: for instance, you can obtain a message’s reply destination
with the statement:
Destination replyDest = inMsg.getJMSReplyTo();
Table 3-6 Message Header Retrieval Methods
Name | Description |
---|---|
|
Get message identifier |
|
Get destination |
|
Get reply destination |
|
Get correlation identifier as string |
|
Get correlation identifier as byte array |
|
Get delivery mode |
|
Get the delivery time |
|
Get priority level |
|
Get time stamp |
|
Get expiration time |
|
Get message type |
|
Get redelivered flag |
Previous | Next | Contents |