JavaTM Message Service 1.1
February 11, 2002
Updated March 04, 2002
Description
Maintenance
version of the JavaTM Message Service specification, version 1.1.
Specification Lead
Kate Stout,
Sun Microsystems, Inc.
Feedback
Rationale for proposed changes
This maintenance
release addresses the unification of the programming interfaces for the Point-to-Point
and Pub/Sub messaging domains in the Java Message Service (JMS) API. In the
existing version of the specification, the client programming model make
a strong distinction between these two domains. One consequence of domain
separation is that actions from the Point-to-Point domain and the Pub/Sub
domain in can not be used in the same transaction.
In this proposed
domain unification of the interfaces, methods have been added to support
the ability to include PTP and Pub/Sub messaging in the same transaction.
In addition, the domain unification proposed simplifies the client programming
model, so that the client programmer can use a simplified set of APIs to create
an application.
This proposal
is
- Fully backwards compatible;
existing implementations will work as is.
- Semantically compatible;
semantic differences between the two messaging domains are retained
The scope
of a transaction in JMS is on a per Session basis. To add the ability to
work across both domains, a number of methods have been added the the javax.jms.Session
interface. Adding these methods supports the creation of javax.jms.MessageConsumers
and javax.jms.MessageProducers for either domain at the Session level, and
support sending and receiving message from either domain within the
same Session. For example, using these proposed methods, an application can
create a transacted Session, and then receive messages from a Queue and send
messages to a Topic within the same transaction. In JMS 1.0.2b, this is not
possible.
In addition to the interface changes for
domain unification, there are several minor specification clarifications and
enhancements are proposed. These have been detailed below in
Other Changes
.
Proposed Changes
Domain unification
The following are the changes proposed to support the unification of the
domain-specific interfaces. It is arranged by alphabetically by interface.
Connection
Add
methods to support domain unification:
ConnectionConsumer
createConnectionConsumer(Destination destination, String messageSelector,
ServerSessionPool sessionPool, int maxMessages) throws JMSException;
ConnectionConsumer createDurableConnectionConsumer(Topic topic,String
subscriptionName, String messageSelector, ServerSessionPool sessionPool,
int maxMessages) throws JMSException;
Session createSession(boolean transacted, int acknowledgeMode) throws
JMSException;
ConnectionFactory
Add
methods to support domain unification:
Connection createConnection() throws JMSException;
Connection createConnection(String userName, String password) throws
JMSException;
MessageProducer
Add methods to support domain unification:
Destination getDestination() throws JMSException;
void send(Message message) throws JMSException;
void send(Message message, int deliveryMode, int priority, long timeToLive)
throws JMSException;
void send(Destination destination, Message message) throws JMSException;
void send(Destination destination, Message message, int deliveryMode,
int priority, long timeToLive) throws JMSException;
Session
Add methods to support domain unification:
MessageProducer createProducer(Destination destination) throws JMSException;
MessageConsumer createConsumer(Destination destination) throws JMSException;
MessageConsumer createConsumer(Destination destination, java.lang.String
messageSelector) throws JMSException;
MessageConsumer createConsumer(Destination destination, java.lang.String
messageSelector, boolean NoLocal) throws JMSException;
TopicSubscriber createDurableSubscriber(Topic topic, java.lang.String
name) throws JMSException;
TopicSubscriber createDurableSubscriber(Topic topic, java.lang.String
name, java.lang.String messageSelector, boolean noLocal) throws JMSException;
QueueBrowser createBrowser(Queue queue) throws JMSException;
QueueBrowser createBrowser(Queue queue, String messageSelector) throws
JMSException;
Queue createQueue(String name) throws JMSException;
Topic createTopic(String name) throws JMSException;
TemporaryTopic createTemporaryTopic() throws JMSException;
TemporaryQueue createTemporaryQueue() throws JMSException;
void unsubscribe(String string name)
XAConnection
Add method to support domain unification
XASession createXASession() throws JMSException;
XAConnectionFactory
Add methods to support domain unification:
XAConnection createXAConnection() throws JMSException;
XAConnection createXAConnection(String userName, String password)
throws JMSException;
BytesMessage
Enhancement: Add method
int getBodyLength() throws JMSException
Added to support the ability to get a body length which can be used to allocate
a bytes array.
Connection
Clarification: If Connection.getExceptionListener is called, and no ExceptionListener
is registered, the JMS provider must return null.
MapMessage
Clarification: For each set method, if the name parameter is null or
empty string, throw NullPointerException
Methods affected: setByte, setBytes, setChar, setDouble,
setFloat,setInt, setLong,setObject, setShort,setString
Message
Clarification: For each set property method, if the property name parameter
is null or empty string, throw NullPointerException.
Methods affected: setBooleanProperty, setByteProperty, setDoubleProperty,
setFloatProperty, setIntProperty, setLongProperty, setObjectProperty, setShortProperty,
setStringProperty
TextMessage
Clarification: Changed a comment that indicated that XML might become
popular to a statement that TextMessage can be used to send XML messages.
Session
Enhancement: Add Method
int getAcknowledgeMode() throws JMSException
This method gets value for how messages are acknowledged. Previously there was no method to get the AcknowledgeMode value.
XA
Clarification: Added a comment that the XA interfaces are primarily used
by JMS providers, and are optional.
Interfaces effected: XAConnection, XAConnectionFactory, XAQueueConnection,
XAQueueConnectionFactory, XAQueueSession, XASession, XATopicConnection, XATopicConnectionFactory,
XATopicSession
Examples of domain unification
of the interfaces
In this section, some code examples of common JMS client tasks are given
to show the current approach and the proposed approach.
Example 1: Setting up a connection and session
JMS 1.0.2b
JMS 1.1
Example
2: Creating a Message Producer to a topic
JMS 1.0.2b
JMS 1.1
Example
3 - Adding a Message Producer to a queue
JMS 1.0.2b
JMS 1.1
Example 1: Setting
up a connection and session.
Use TopicConnectionFactory, TopicConnection and TopicSession to setup.
Context jndiContext = null;
TopicConnectionFactory topicConnectionFactory = null;
TopicConnection topicConnection = null;
TopicSession topicSession = null;
Topic topic = null;
//Create a JNDI InitialContext object if none exists yet.
jndiContext = new InitialContext();
// Look up connection factory and topic.
topicConnectionFactory = (TopicConnectionFactory)
jndiContext.lookup("TopicConnectionFactory");
topic = (Topic) jndiContext.lookup("StockQuoteTopic");
//Establish TopicConnection and TopicSession
topicConnection = topicConnectionFactory.createConnection();
topicSession = topicConnection.createTopicSession(false,
Session.AUTO_ACKNOWLEDGE);
JMS 1.1
Use ConnectionFactory, Connection and Session to setup.
Context jndiContext = null;
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
Topic topic = null;
// Create a JNDI InitialContext object if none exists yet.
jndiContext = new InitialContext();
// Look up connection factory and topic.
connectionFactory = (ConnectionFactory)
jndiContext.lookup("TopicConnectionFactory");
topic = (Topic) jndiContext.lookup("StockQuoteTopic");
//Establish Connection and Session
connection = connectionFactory.createConnection();
session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
Example
2: Creating a message producer (to a topic)
Set a message producer that can send messages
JMS 1.0.2.b
Sets up a TopicPublisher and sends messages on a TopicSession
// Create a TopicPublisher and send a message
TopicPublisher topicPublisher = null;
topicPublisher = topicSession.createPublisher(topic);
message = topicSession.createTextMessage("A message body");
topicPublisher.publish(message);
Sets up a MessageProducer and sends messages on a Session.
// Create a Message Producer and send a message
MessageProducer messageProducer = null;
messageProducer = session.createProducer((Destination)topic);
message = session.createTextMessage("A message body");
messageProducer.send(message);
Example
3: Adding a Message Producer to a queue
The client programming simplification can be seen if we now try to add a
Message producer that will send messages to a Queue.
JMS 1.0.2b
To do this, the application must:
Lookup QueueConnectionFactory
Lookup Queue
Create QueueConnection
Create QueueSession
Create QueueSender
Create Message
send message using QueueSender.send();
QueueConnectionFactory queueConnectionFactory = null;
QueueConnection queueConnection = null;
QueueSession queueSession = null;
Queue queue = null;
// Look up connection factory and queue.
queueConnectionFactory = (QueueConnectionFactory)
jndiContext.lookup("QueueConnectionFactory");
queue = (Queue) jndiContext.lookup("WorkFlowQueue");
//Establish QueueConnection and QueueSession
queueConnection = queueConnectionFactory.createQueueConnection();
queueSession = queueConnection.createQueueSession(false,Session.AUTO_ACKNOWLEDGE);
// Setup queue sender
QueueSender queueSender = null;
queueSender = queueSession.createSender(queue);
message = queueSession.createTextMessage("A message body");
queueSender.send(message);
JMS 1.1
By contrast, the unified model can re-use the Connection and Session that
has already been established. The additional steps are:
// Lookup Queue
queue = (Queue) jndiContext.lookup("WorkFlowQueue");
// setup Message producer
MessageProducer workFlowProducer = null;
workFlowProducer = session.createProducer((Destination)queue);
message = session.createTextMessage("A message body");
workFlowProducer.send(message);