Java™ Message Service: 2550 Garcia Avenue Mountain View, Ca 94043 U.S.A. 408-343-1400 Javasoft
Java™ Message Service: 2550 Garcia Avenue Mountain View, Ca 94043 U.S.A. 408-343-1400 Javasoft
JMSisanAPIforaccessingenterprisemessagingsystemsfromJava
programs.
Version1.0.2 November9,1999
Pleasesendtechnicalcommentsonthisspecificationto:
jets-jms@eng.sun.com
Pleasesendproductandbusinessquestionsto:
jets-jms-business@eng.sun.com
MarkHapner,SeniorStaffEngineer
RichBurridge,StaffEngineer
RahulSharma,StaffEngineer
SunMicrosystems,JavaSoftware
JavaSoft
2550 Garcia Avenue
Mountain View, CA 94043 U.S.A.
408-343-1400
Java Message Service Specification ("Specification")
Version: 1.0.2
Status: Final Release
Release: 12/17/99
NOTICE.
This Specification is protected by copyright and the information described herein may be protected by one or more U.S. patents, foreign
patents, or pending applications. Except as provided under the following license, no part of this Specification may be reproduced in any
form by any means without the prior written authorization of Sun Microsystems, Inc. (Sun) and its licensors, if any. Any use of this
Specification and the information described herein will be governed by these terms and conditions and the Export Control and General
Terms as set forth in Sun's website Legal Terms. By viewing, downloading or otherwise copying this Specification, you agree that you have
read, understood, and will comply with all the terms and conditions set forth herein.
Sun hereby grants you a fully-paid, non-exclusive, non-transferable, worldwide, limited license (without the right to sublicense), under
Sun's intellectual property rights that are essential to practice this Specification, to internally practice this Specification solely for the
purpose of creating a clean room implementation of this Specification that: (i) includes a complete implementation of the current version of
this Specification, without subsetting or supersetting; (ii) implements all of the interfaces and functionality of this Specification, as defined
by Sun, without subsetting or supersetting; (iii) includes a complete implementation of any optional components (as defined by Sun in this
Specification) which you choose to implement, without subsetting or supersetting; (iv) implements all of the interfaces and functionality of
such optional components, without subsetting or supersetting; (v) does not add any additional packages, classes or interfaces to the
"java.*" or "javax.*" packages or subpackages (or other packages defined by Sun); (vi) satisfies all testing requirements available from Sun
relating to the most recently published version of this Specification six (6) months prior to any release of the clean room implementation or
upgrade thereto; (vii) does not derive from any Sun source code or binary code materials; and (viii) does not include any Sun source code or
binary code materials without an appropriate and separate license from Sun. This Specification contains the proprietary information of Sun
and may only be used in accordance with the license terms set forth herein. This license will terminate immediately without notice from
Sun if you fail to comply with any provision of this license. Sun may, at its sole option, terminate this license without cause upon ten (10)
days notice to you. Upon termination of this license, you must cease use of or destroy this Specification.
TRADEMARKS.
No right, title, or interest in or to any trademarks, service marks, or trade names of Sun or Sun's licensors is granted hereunder. Sun, Sun
Microsystems, the Sun logo, Java, Enterprise JavaBeans, Java Compatible, JDK, JDBC, JavaBeans, JavaMail, Write Once, Run Anywhere,
and Java Naming and Directory Interface are trademarks or registered trademarks of Sun Microsystems, Inc. in the U.S. and other
countries.
DISCLAIMER OF WARRANTIES.
THIS SPECIFICATION IS PROVIDED "AS IS". SUN MAKES NO REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
OR NON-INFRINGEMENT THAT THE CONTENTS OF THE SPECIFICATION ARE SUITABLE FOR ANY PURPOSE OR THAT ANY
PRACTICE OR IMPLEMENTATION OF SUCH CONTENTS WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS,
TRADE SECRETS OR OTHER RIGHTS. This document does not represent any commitment to release or implement any portion of this
Specification in any product.
THIS SPECIFICATION COULD INCLUDE TECHNICAL INACCURACIES OR TYPOGRAPHICAL ERRORS. CHANGES ARE
PERIODICALLY ADDED TO THE INFORMATION HEREIN; THESE CHANGES WILL BE INCORPORATED INTO NEW VERSIONS OF
THE SPECIFICATION, IF ANY. SUN MAY MAKE IMPROVEMENTS AND/OR CHANGES TO THE PRODUCT(S) AND/OR THE
PROGRAM(S) DESCRIBED IN THIS SPECIFICATION AT ANY TIME. Any use of such changes in the Specification will be governed by
the then-current license for the applicable version of the Specification.
LIMITATION OF LIABILITY.
TO THE EXTENT NOT PROHIBITED BY LAW, IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY DAMAGES,
INCLUDING WITHOUT LIMITATION, LOST REVENUE, PROFITS OR DATA, OR FOR SPECIAL, INDIRECT, CONSEQUENTIAL,
INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT
OF OR RELATED TO ANY FURNISHING, PRACTICING, MODIFYING OR ANY USE OF THE SPECIFICATION, EVEN IF SUN
AND/OR ITS LICENSORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
You will indemnify, hold harmless, and defend Sun and its licensors from any claims arising or resulting from: (i) your use of the
Specification; (ii) the use or distribution of your Java application, applet and/or clean room implementation; and/or (iii) any claims that
later versions or releases of any Specification furnished to you are incompatible with the Specification provided to you under this license.
Please
Recycle
RESTRICTED RIGHTS LEGEND.
Use, duplication, or disclosure by the U.S. Government is subject to the restrictions set forth in this license and as provided in DFARS
227.7202-1(a) and 227.7202-3(a) (1995), DFARS 252.227-7013(c)(1)(ii)(Oct 1988), FAR 12.212(a) (1995), FAR 52.227-19 (June 1987), or FAR
52.227-14(ALT III) (June 1987), as applicable.
REPORT.
You may wish to report any ambiguities, inconsistencies, or inaccuracies you may find in connection with your use of the Specification
("Feedback"). To the extent that you provide Sun with any Feedback, you hereby: (i) agree that such Feedback is provided on a non-
proprietary and non-confidential basis and (ii) grant Sun a perpetual, non-exclusive, worldwide, fully paid-up, irrevocable license, with
the right to sublicense through multiple levels of sublicensees, to incorporate, disclose, and use without limitation the Feedback for any
purpose related to the Specification and future versions, implementations, and test suites thereof.
Please
Recycle
Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.1 Abstract . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.2 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.2.1 Is This a Mail API? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1.2.2 Existing Messaging Systems . . . . . . . . . . . . . . . . . . . . . 15
1.2.3 JMS Objectives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
1.2.3.1 JMS Provider . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
1.2.3.2 JMS Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
1.2.3.3 JMS Domains . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
1.2.3.4 Portability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
1.2.4 What JMS Does Not Include . . . . . . . . . . . . . . . . . . . . . 17
1.3 What Is Required by JMS . . . . . . . . . . . . . . . . . . . . . . . 18
1.4 Relationship to Other JavaSoft Enterprise APIs . . . . 18
1.4.1 JDBC. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.4.2 JavaBeans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.4.3 Enterprise Java Beans . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.4.4 Java Transaction (JTA) . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.4.5 Java Transaction Service (JTS). . . . . . . . . . . . . . . . . . . . 19
1.4.6 Java Naming and Directory Service (JNDI) . . . . . . . . 19
2. Architecture. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.2 What is a JMS Application? . . . . . . . . . . . . . . . . . . . . . 20
2.3 Administration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
vi
2.4 Two Messaging Styles . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.5 JMS Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.6 Developing a JMS Application . . . . . . . . . . . . . . . . . . 23
2.6.1 Developing a JMS Client . . . . . . . . . . . . . . . . . . . . . . . . 23
2.7 Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.8 Multi-Threading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.9 Triggering Clients . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.10 Request/Reply . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3. JMS Message Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.1 Background . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.2 Goals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.3 JMS Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
3.4 Message Header Fields . . . . . . . . . . . . . . . . . . . . . . . . . 27
3.4.1 JMSDestination . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
3.4.2 JMSDeliveryMode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
3.4.3 JMSMessageID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
3.4.4 JMSTimestamp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
3.4.5 JMSCorrelationID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
3.4.6 JMSReplyTo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
3.4.7 JMSRedelivered . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
3.4.8 JMSType. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
3.4.9 JMSExpiration. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
3.4.10 JMSPriority . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
3.4.11 How Message Header Values Are Set . . . . . . . . . . . . . 32
3.4.12 Overriding Message Header Fields . . . . . . . . . . . . . . . 32
3.5 Message Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
3.5.1 Property Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
3.5.2 Property Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
3.5.3 Using Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
3.5.4 Property Value Conversion . . . . . . . . . . . . . . . . . . . . . . 33
3.5.5 Property Values as Objects . . . . . . . . . . . . . . . . . . . . . . 34
3.5.6 Property Iteration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.5.7 Clearing a Messages Property Values. . . . . . . . . . . . . 35
3.5.8 Non-existent Properties . . . . . . . . . . . . . . . . . . . . . . . . . 35
3.5.9 JMS Defined Properties . . . . . . . . . . . . . . . . . . . . . . . . . 35
3.5.10 Provider-Specific Properties . . . . . . . . . . . . . . . . . . . . . 37
3.6 Message Acknowledgment . . . . . . . . . . . . . . . . . . . . . 37
Contents viii
4.4.8 Distributed Transactions . . . . . . . . . . . . . . . . . . . . . . . . 59
4.4.9 Multiple Sessions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
4.4.10 Message Order . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
4.4.10.1 Order of Message Receipt . . . . . . . . . . . . . . . . . . . . . . 60
4.4.10.2 Order of Message Sends . . . . . . . . . . . . . . . . . . . . . . . . 60
4.4.11 Message Acknowledgment . . . . . . . . . . . . . . . . . . . . . . 61
4.4.12 Duplicate Delivery of Messages . . . . . . . . . . . . . . . . . . 62
4.4.13 Duplicate Production of Messages. . . . . . . . . . . . . . . . 62
4.4.14 Serial Execution of Client Code . . . . . . . . . . . . . . . . . . 62
4.4.15 Concurrent Message Delivery . . . . . . . . . . . . . . . . . . . 63
4.5 MessageConsumer . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
4.5.1 Synchronous Delivery . . . . . . . . . . . . . . . . . . . . . . . . . . 63
4.5.2 Asynchronous Delivery. . . . . . . . . . . . . . . . . . . . . . . . . 64
4.6 MessageProducer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
4.7 Message Delivery Mode . . . . . . . . . . . . . . . . . . . . . . . . 65
4.8 Message Time-To-Live . . . . . . . . . . . . . . . . . . . . . . . . . 65
4.9 Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
4.10 Reliability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
5. JMS Point-to-Point Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
5.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
5.2 Queue Management . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
5.3 Queue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
5.4 TemporaryQueue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
5.5 QueueConnectionFactory . . . . . . . . . . . . . . . . . . . . . . . 69
5.6 QueueConnection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
5.7 QueueSession . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
5.8 QueueReceiver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
5.9 QueueSender . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
5.10 QueueBrowser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
5.11 QueueRequestor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
5.12 Reliability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
6. JMS Publish/Subscribe Model . . . . . . . . . . . . . . . . . . . . . . . . . 72
6.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
6.2 Pub/Sub Latency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
6.3 Durable Subscription . . . . . . . . . . . . . . . . . . . . . . . . . . 73
6.4 Topic Management . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Contents x
9.1.2.2 Getting a Message Queue . . . . . . . . . . . . . . . . . . . . . . . 91
9.1.2.3 Getting a QueueConnection . . . . . . . . . . . . . . . . . . . . . 91
9.1.2.4 Getting a QueueSession . . . . . . . . . . . . . . . . . . . . . . . . 91
9.1.2.5 Getting a QueueSender . . . . . . . . . . . . . . . . . . . . . . . . 92
9.1.2.6 Getting a QueueReceiver . . . . . . . . . . . . . . . . . . . . . . . 92
9.1.2.7 Start Delivery of Messages . . . . . . . . . . . . . . . . . . . . . . 92
9.1.3 Publish/Subscribe Messaging Domain Setup . . . . . . 92
9.1.3.1 Getting a TopicConnectionFactory . . . . . . . . . . . . . . . 93
9.1.3.2 Getting a Message Topic . . . . . . . . . . . . . . . . . . . . . . . . 93
9.1.3.3 Getting a TopicConnection . . . . . . . . . . . . . . . . . . . . . . 93
9.1.3.4 Getting a TopicSession . . . . . . . . . . . . . . . . . . . . . . . . . 93
9.1.3.5 Getting a TopicSubscriber . . . . . . . . . . . . . . . . . . . . . . 94
9.1.3.6 Getting a TopicPublisher . . . . . . . . . . . . . . . . . . . . . . . 94
9.1.3.7 Start Delivery of Messages . . . . . . . . . . . . . . . . . . . . . . 95
9.1.4 JMS Message Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
9.1.4.1 Using a BytesMessage . . . . . . . . . . . . . . . . . . . . . . . . . 95
9.1.4.2 Using a TextMessage . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
9.1.4.3 Using a MapMessage . . . . . . . . . . . . . . . . . . . . . . . . . . 96
9.1.4.4 Using a StreamMessage . . . . . . . . . . . . . . . . . . . . . . . . 97
9.1.4.5 Using an ObjectMessage . . . . . . . . . . . . . . . . . . . . . . . . 97
9.1.5 Point-to-Point Sending and Receiving. . . . . . . . . . . . . 98
9.1.5.1 Sending a Message . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
9.1.5.2 Receiving a Message . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
9.1.6 Publish/Subscribe Sending and Receiving . . . . . . . . . 98
9.1.6.1 Sending a Message . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
9.1.6.2 Receiving a Message . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
9.1.7 Unpacking messages . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
9.1.7.1 Unpacking a BytesMessage . . . . . . . . . . . . . . . . . . . . . 99
9.1.7.2 Unpacking a TextMessage . . . . . . . . . . . . . . . . . . . . . . 99
9.1.7.3 Unpacking a MapMessage . . . . . . . . . . . . . . . . . . . . . . 99
9.1.7.4 Unpacking a StreamMessage . . . . . . . . . . . . . . . . . . . . 100
9.1.7.5 Unpacking an ObjectMessage . . . . . . . . . . . . . . . . . . . 100
9.1.8 Message Selection. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
9.1.8.1 Point-To-Point QueueReceiver Setup . . . . . . . . . . . . . 101
9.1.8.2 Publish/Subscribe TopicSubscriber Setup . . . . . . . . . 101
10. Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
10.1 Resolved Issues. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Contents xii
11.2.21 JMS Source JavaDoc Clarifications. . . . . . . . . . . . . . . . 110
1.1 Abstract
This specification describes the objectives and functionality of the Java
Message Service (JMS).
JMS provides a common way for Java programs to create, send, receive and
read an enterprise messaging systems messages.
1.2 Overview
Enterprise messaging products (or as they are sometimes called, Message
Oriented Middleware products) are becoming an essential component for
integrating intra-company operations. They allow separate business
components to be combined into a reliable, yet flexible, system.
In addition to the traditional MOM vendors, enterprise messaging products are
also provided by several database vendors and a number of internet related
companies.
Java language clients and Java language middle tier services must be capable
of using these messaging systems. JMS provides a common way for Java
language programs to access these systems.
JMS is a set of interfaces and associated semantics that define how a JMS client
accesses the facilities of an enterprise messaging product.
14
1
Since messaging is peer-to-peer, all users of JMS are referred to generically as
clients. A JMS application is made up of a set of application defined messages
and a set of clients that exchange them.
Ideally, JMS providers will be written in 100% Pure Java so they can run in
applets; simplify installation; and, work across architectures and OSs.
A major goal of JMS is that clients have a consistent API for creating and
working with messages which is independent of JMS provider.
Point-to-point (PTP) products are built around the concept of message queues.
Each message is addressed to a specific queue; clients extract messages from
the queue(s) established to hold their messages.
IntroductionNovember 9, 1999 16
1
Publish and subscribe (Pub/Sub) clients address messages to some node in a
content hierarchy. Publishers and subscribers are generally anonymous and
may dynamically publish or subscribe to the content hierarchy. The system
takes care of distributing the messages arriving from a nodes multiple
publishers to its multiple subscribers.
1.2.7 Portability
The primary portability objective is that new, JMS only, applications are
portable across products within the same messaging domain.
1.4.1 JDBC
JMS clients may also use JDBC. They may desire to include the use of both
JDBC and JMS in the same transaction. In most cases, this will be achieved
automatically by implementing these clients as Enterprise JavaBeans. It will
also be possible to do this directly with JTA.
1.4.2 JavaBeans
JavaBeans can use a JMS session to send/receive messages. JMS itself is an API
and the interfaces it defines are not designed to be used directly as Java beans.
The current EJB specification defines beans that are invoked synchronously via
method calls from EJB clients. A future release of EJB will add a form of
asynchronous bean that is invoked when a JMS client sends it a message.
IntroductionNovember 9, 1999 18
1
A JMS client may use JTA to delimit distributed transactions; however, this is a
function of the transaction environment the client is running in. It is not a
feature of JMS per se.
2.1 Overview
This chapter describes the environment of message based applications and the
role JMS plays in this environment.
20
2
2.3 Administration
It is expected that each JMS provider will differ significantly in their
underlying messaging technology. It is also expected there will be major
differences in how a providers system is installed and administered.
If JMS clients are to be portable, they must be isolated from these proprietary
aspects of a provider. This is done by defining JMS administered objects that
are created and customized by a providers administrator and later used by
clients. The client uses them through JMS interfaces that are portable. The
administrator creates them using provider-specific facilities.
JMS defines these two styles because they represent the two dominant
approaches to messaging currently in use. Since many messaging systems only
support one of these styles, JMS provides a separate domain for each and
defines compliance for each domain.
The following provides a brief definition of these JMS concepts. See the PTP
and Pub/Sub chapters for more information.
ConnectionFactory - an administered object used by a client to create a
Connection
Connection - An active connection to a JMS provider
Destination - encapsulates the identity of a message destination
Session - a single threaded context for sending and receiving messages
MessageProducer - an object created by a Session that is used for sending
messages to a destination
MessageConsumer - an object created by a Session that is used for receiving
messages sent to a destination
The term consume is used in this document to mean the receipt of a message by
a JMS client, i.e. a JMS provider has received a message and has given it to its
client. Since JMS supports both synchronous and asynchronous receipt of
messages, the term consume is used when there is no need to make a distinction
between them.
The term produce is used as the most general term for sending a message. It
means giving a message to a JMS provider for delivery to a destination.
ArchitectureNovember 9, 1999 22
2
The message definitions used by an application may originate with JMS or they
may have been defined by the non-JMS part of the application.
At this point a client has the basic JMS setup needed to produce and consume
messages.
2.7 Security
JMS does not provide features for controlling or configuring message integrity
or message privacy.
It is expected that many JMS providers will provide such features. It is also
expected that configuration of these services will be handled by provider-
specific administration tools. Clients will get the proper security configuration
as part of the administered objects they use.
2.8 Multi-Threading
JMS could have required that all its objects support concurrent use. Since
support for concurrent access typically adds some overhead and complexity,
the JMS design restricts its requirement for concurrent access to those objects
that would naturally be shared by a multi-threaded client. The remainder are
designed to be accessed by one logical thread of control at a time.
JMS defines some specific rules that restrict the concurrent use of Sessions.
Since they require more knowledge of JMS specifics than we have presented at
this point, they will be described later. Here we will describe the rationale for
imposing them.
There are two reasons for restricting concurrent access to Sessions. First,
Sessions are the JMS entity that supports transactions. It is very difficult to
implement transactions that are multi-threaded. Second, Sessions support
asynchronous message consumption. It is important that JMS not require that
client code used for asynchronous message consumption be capable of
handling multiple, concurrent messages. In addition, if a Session has been set
up with multiple, asynchronous consumers, it is important that the client is not
forced to handle the case where these separate consumers are concurrently
executing. These restrictions make JMS easier to use for typical clients. More
sophisticated clients can get the concurrency they desire by using multiple
sessions.
ArchitectureNovember 9, 1999 24
2
JMS does not provide a mechanism for triggering the execution of a client.
Some providers may supply such a triggering mechanism via their
administrative facilities.
2.10 Request/Reply
JMS provides the JMSReplyTo message header field for specifying the
Destination where a reply to a message should be sent. The JMSCorrelationID
header field of the reply can be used to reference the original request. See
Section 3.4, Message Header Fields for more information.
In addition, JMS provides a facility for creating temporary queues and topics
that can be used as a unique destination for replies.
3.1 Background
Enterprise messaging products treat messages as lightweight entities that
consist of a header and a body. The header contains fields used for message
routing and identification; the body contains the application data being sent.
Within this general form, the definition of a message varies significantly across
products. There are major differences in the content and semantics of headers.
Some products use a self describing, canonical encoding of message data;
others treat data as completely opaque. Some products provide a repository for
storing message descriptions that can be used to identify and interpret
message content; others dont.
It would be quite difficult for JMS to capture the breadth of this, sometimes
conflicting, union of message models.
3.2 Goals
The JMS message model has the following goals:
Provide a single, unified message API
Provide an API suitable for creating messages that match the format used by
existing, non-JMS applications
Support the development of heterogeneous applications that span operating
systems, machine architectures, and computer languages
Support messages containing Java objects
26
3
Support messages containing Extensible Markup Language pages (see
http://www.w3.org/XML).
3.4.1 JMSDestination
The JMSDestination header field contains the destination to which the message
is being sent.
When a message is sent this value is ignored. After completion of the send it
holds the destination object specified by the sending method.
3.4.2 JMSDeliveryMode
The JMSDeliveryMode header field contains the delivery mode specified when
the message was sent.
When a message is sent this value is ignored. After completion of the send it
holds the delivery mode specified by the sending method.
3.4.3 JMSMessageID
The JMSMessageID header field contains a value that uniquely identifies each
message sent by a provider.
All JMSMessageID values must start with the prefix ID:. Uniqueness of
message ID values across different providers is not required.
Since message IDs take some effort to create and increase a messages size,
some JMS providers may be able to optimize message overhead if they are
given a hint that message ID is not used by an application. JMS
MessageProducer provides a hint to disable message ID. When a client sets a
producer to disable message ID it is saying that it does not depend on the
value of message ID for the messages it produces. These messages must either
have message ID set to null or, if the hint is ignored, message ID must be set to
its normal unique value.
3.4.4 JMSTimestamp
The JMSTimestamp header field contains the time a message was handed off to
a provider to be sent. It is not the time the message was actually transmitted
because the actual send may occur later due to transactions or other client side
queueing of messages.
Since timestamps take some effort to create and increase a messages size, some
JMS providers may be able to optimize message overhead if they are given a
hint that timestamp is not used by an application. JMS MessageProducer
provides a hint to disable timestamps. When a client sets a producer to disable
timestamps it is saying that it does not depend on the value of timestamp for
the messages it produces. These messages must either have timestamp set to
zero or, if the hint is ignored, timestamp must be set to its normal value.
3.4.5 JMSCorrelationID
A client can use the JMSCorrelationID header field to link one message with
another. A typically use is to link a response message with its request message.
If a provider supports the native concept of correlation ID, a JMS client may
need to assign specific JMSCorrelationID values to match those expected by
non-JMS clients. A byte[] value is used for this purpose. JMS providers without
native correlation ID values are not required to support byte[] values*. The use
of a byte[] value for JMSCorrelationID is non-portable.
3.4.6 JMSReplyTo
The JMSReplyTo header field contains a Destination supplied by a client when
a message is sent. It is the destination where a reply to the message should be
sent.
3.4.7 JMSRedelivered
If a client receives a message with the JMSRedelivered indicator set, it is likely,
but not guaranteed, that this message was delivered to the client earlier but the
client did not acknowledge its receipt at that earlier time. See Section 4.4.13,
Message Acknowledgment for more information.
This header field has no meaning on send and is left unassigned by the
sending method.
3.4.8 JMSType
The JMSType header field contains a message type identifier supplied by a
client when a message is sent.
Some JMS providers use a message repository that contains the definition of
messages sent by applications. The type header field may reference a messages
definition in the providers repository.
JMS does not define a standard message definition repository nor does it
define a naming policy for the definitions it contains.
Some messaging systems require that a message type definition for each
application message be created and that each message specify its type. In order
to work with such JMS providers, JMS clients should assign a value to JMSType
whether the application makes use of it or not. This insures that it is properly
set for those providers that require it.
To insure portability, JMS clients should use symbolic values for JMSType that
can be configured at installation time to the values defined in the current
3.4.9 JMSExpiration
When a message is sent, its expiration time is calculated as the sum of the time-
to-live value specified on the send method and the current GMT. On return
from the send method, the messages JMSExpiration header field contains this
value. When a message is received its JMSExpiration header field contains this
same value.
Clients should not receive messages that have expired; however, JMS does not
guarantee that this will not happen.
3.4.10 JMSPriority
The JMSPriority header field contains the messages priority.
When a message is sent this value is ignored. After completion of the send it
holds the value specified by the method sending the message.
JMS defines a ten level priority value with 0 as the lowest priority and 9 as the
highest. In addition, clients should consider priorities 0-4 as gradations of
normal priority and priorities 5-9 as gradations of expedited priority.
JMS does not require that a provider strictly implement priority ordering of
messages; however, it should do its best to deliver expedited messages ahead
of normal messages.
JMS does not define specifically how an administrator overrides these header
field values. A JMS provider is not required to support this administrative
option.
Properties allow a client, via message selectors (see Section 3.8, Message
Selection), to have a JMS provider select messages on its behalf using
application-specific criteria.
See Section 3.8, Message Selection for more information about JMS message
properties.
Table 0-4 A value set as the row type can be read as the column type
The getObjectProperty method only returns values of null, Boolean, Byte, Short,
Integer, Long, Float, Double and String. A null value is returned if a property by
the specified name does not exist.
The getPropertyNames method does not return the names of the JMS standard
header fields.
Clearing a messages property entries does not clear the value of its body.
JMS does not provide a way to remove an individual property entry once it has
been added to a message.
Unless noted otherwise, support for these properties is optional. The String[]
ConnectionMetaData.getJMSXPropertyNames() method returns the names of the
JMSX properties supported by a connection.
The existence, in a particular message, of JMS defined properties that are set by
a JMS Provider depends on how a particular provider controls use of the
Table 0-5
The case of these JMSX property names must be as defined in the table above.
Unless specifically noted, the values and semantics of the JMSX properties are
undefined.
In the case where a message is sent to a single receiver, this can be done with
reasonable efficiency by putting the criteria in the message and having the
receiving client discard the ones its not interested in.
JMS provides a facility that allows clients to delegate message selection to their
JMS provider. This simplifies the work of the client and allows JMS providers
to eliminate the time and bandwidth they would otherwise waste sending
messages to clients that dont need them.
Predefined selector literals and operator names are written here in upper case;
however, they are case insensitive.
* See X/Open CAE Specification Data Management: Structured Query Language (SQL), Version 2, ISBN: 1-
85912-151-9 March 1996.
The following message selector selects messages with a message type of car
and color of blue and weight greater than 2500 lbs:
The boolean operators use three valued logic as defined by the following
tables:
AND T F U
T T F U
F F F F
U U F U
OR T F U
T T T T
F T F U
U T U U
NOT
T F
F T
U U
Date and time values should use the standard Java long millis value. When
including a date or time literal in a message selector, it should be an integer
literal for a millis value. The standard way to produce millis values is to use
java.util.Calendar.
The rationale for the read-only restriction is that it gives JMS Providers more
freedom in how they implement the management of received messages. For
instance, they may return a message object that references property entries and
body values that reside in an internal message buffer rather than being forced
to make a copy.
The types can be read or written explicitly using methods for each type. They
may also be read or written generically as objects. For instance, a call to
MapMessage.setInt(foo, 6) is equivalent to MapMessage.setObject(foo, new
Integer(6)). Both forms are provided because the explicit form is convenient for
static programming and the object form is needed when types are not known
at compile time.
Getting a MapMessage field for a field name which has not been set is handled
as if the field exists with a null value.
Table 0-9 A value written as the row type can be read as the column type
boolean byte short char int long float double String byte[]
boolean X X
byte X X X X X
short X X X X
char X X
int X X X
long X X
float X X X
double X X
String X X X X X X X X
byte[] X
For instance, when a client is using a JMS provider that supports a native map
message; and, it wishes to send a map message that can be read by both JMS
and native clients, it uses a MapMessage. When the message is sent, the
provider translates it into its native form. Native clients can then receive it. If a
JMS provider receives it, the provider translates it back into a MapMessage.
Each JMS provider provides its own implementation of its Sessions message
creation methods. This allows a provider to use message implementations that
are tailored to its needs.
The JMS message interfaces provide write/set methods for setting object
values in a message body and message properties. All of these methods must
be implemented to copy their input objects into the message. The value of an
input object is allowed to be null and will return null when accessed. One
exception to this is that BytesMessage does not support the concept of a null
stream and attempting to write a null into it must throw
java.lang.NullPointerException.
The JMS message interfaces provide read/get methods for accessing objects in
a message body and message properties. All of these methods must be
implemented to return a copy of the accessed message objects.
4.1 Overview
This chapter describes the JMS facilities that are shared by both the PTP and
Pub/Sub domains.
Although the interfaces for administered objects do not explicitly depend on JNDI,
JMS establishes the convention that JMS clients find them by looking them up in a
namespace using JNDI.
An administrator can place an administered object anywhere in a namespace.
JMS does not define a naming policy.
48
4
An administered object should not hold on to any remote resources. Its lookup
should not use remote resources other than those used by JNDI itself.
It is expected that JMS providers will provide the tools an administrator needs
to create and configure administered objects in a JNDI namespace. JMS
provider implementations of administered objects should be both
javax.naming.Referenceable and java.io.Serializable so that they can be stored in all
JNDI naming contexts. In addition, it is recommended that these
implementations follow the JavaBeansTM design patterns.
4.2.1 Destination
JMS does not define a standard address syntax. Although this was considered,
it was decided that the differences in address semantics between existing
enterprise messaging products was too wide to bridge with a single syntax.
Instead, JMS defines the Destination object which encapsulates provider-specific
addresses.
4.2.2 ConnectionFactory
A ConnectionFactory encapsulates a set of connection configuration parameters
that has been defined by an administrator. A client uses it to create a
Connection with a JMS provider.
4.3 Connection
A JMS Connection is a clients active connection to its JMS provider. It will
typically allocate provider resources outside the Java virtual machine.
4.3.1 Authentication
When creating a connection, a client may specify their credentials as
name/password.
If no credentials are specified, the current threads credentials are used. At this
point, the JDK does not define the concept of a threads default credentials;
however, it is likely this will be defined in the near future. For now, the
identity of the user under which the JMS client is running should be used.
If a client explicitly does the set it must do this immediately after creating the
connection and before any other action on the connection is taken. After this
point, setting the client identifier is a programming error that should throw an
IllegalStateException.
The purpose of client identifier is to associate a connection and its objects with
a state maintained on behalf of the client by a provider. By definition, the client
state identified by a client identifier can only be in use by one client at a time.
A JMS provider must prevent concurrently executing clients from using it.
This prevention may take the form of JMSExceptions thrown when such use is
attempted; it may result in the offending client being blocked; or some other
solution. A JMS provider must insure that such attempted sharing of an
individual client state does not result in messages being lost or doubly
processed.
The only individual client state identified by JMS is that required to support
durable subscriptions, see Section 6.3, Durable Subscription for more
information.
A Connection can immediately be started and the setup can be done afterwards.
Clients that do this must be prepared to handle asynchronous message
delivery while they are still in the process of setting up.
A stop method call must not return until delivery of messages has paused. This
means a client can rely on the fact that none of its message listeners will be
called and all threads of control waiting for receive to return will not return
with a message until the connection is restarted. The receive timers for a
stopped connection continue to advance so receives may time out and return a
null message while the connection is stopped.
If MessageListeners are running when stop is invoked, stop must wait until all
of them have returned before it may return. While these MessageListeners are
completing they must have the full services of the connection available to
them.
Note that in this case, the message consumer will likely get an exception if it is
attempting to use the facilities of the now closed connection while processing
its last message. A developer must take this last message case into account
Once a connection has been closed an attempt to use it or its sessions or their
message consumers and producers must throw an IllegalStateException (calls to
the close method of these objects must be ignored). It is valid to continue to use
message objects created or received via the connection with the exception of a
received messages acknowledge method.
4.3.6 Sessions
A Connection is a factory for Sessions that use its underlying connection to a
JMS provider for producing and consuming messages.
* The term transacted session refers to the case where a sessions commit and rollback methods are used to
demarcate a transaction local to the session. In the case where a sessions work is coordinated by an external
transaction manager, a sessions commit and rollback methods are not used and the result of a closed ses-
sions work is determined later by the transaction manager.
4.3.7 ConnectionMetaData
A Connection provides a ConnectionMetaData object. This object provides the
latest version of JMS supported by the provider as well as the providers
product name and version.
It also provides a list of the JMS defined property names supported by the
connection.
4.3.8 ExceptionListener
If a JMS provider detects a problem with a connection it will inform the
connections ExceptionListener if one has been registered. It does this by calling
the listeners onException() method passing it a JMSException describing the
problem.
The exceptions delivered to ExceptionListener are those which dont have any
other place to be reported. If an exception is thrown on a JMS call it, by
definition, must not be delivered to an ExceptionListener (i.e. ExceptionListener is
not for the purpose of monitoring all exceptions thrown by a connection).
4.4 Session
A JMS Session is a single threaded context* for producing and consuming
messages. Although it may allocate provider resources outside the Java virtual
machine, it is considered a light-weight JMS object.
* There are no restrictions on the number of threads that can use a Session object or those it creates. The restric-
tion is that the resources of a Session should not be used concurrently by multiple threads. It is up to the user
to insure that this concurrency restriction is met. The simplest way to do this is to use one thread. In the case
of asynchronous delivery, use one thread for setup in stopped mode and then start asynchronous delivery.
In more complex cases the user must provide explicit synchronization.
Session close terminates all message processing on the session. It must handle
the shutdown of pending receives by the sessions consumers or a running
message listener as described in Section 4.3.5, Closing a Connection.
Session close is the only session method that may be invoked from a thread of
control separate from the one which is currently controlling the session.
When session close is invoked it should not return until its message processing
has been orderly shut down. This means that none of its message listeners are
running and that if there is a pending receive it has returned with either null or
a message.
Although a session may create multiple producers and consumers, they are
restricted to serial use. In effect, only a single logical thread of control can use
them. This is explained in more detail later.
Sessions must be capable of sending all JMS messages regardless of how they
may be implemented.
Another typical use is to have one thread set up a session by creating its
producers and one or more asynchronous consumers. In this case, the message
producers are exclusively for the use of the consumers message listeners.
Since the session serializes execution of its consumers MessageListeners, they
can safely share the resources of their session.
If a connection is left in stopped mode while its sessions are being set up, a
client does not have to deal with messages arriving before the client is fully
prepared to handle them. This is the preferred strategy because it eliminates
the possibility of unanticipated conflicts between setup and message
processing. It is possible to create and set up a session while a connection is
receiving messages. In this case, more care is required to insure that a sessions
MessageProducers, MessageConsumers and MessageListeners are created in the
right order. For instance, a bad order may cause a MessageListener to use a
Once a connection has been started, all its sessions with a registered message
listener are dedicated to the thread of control that delivers messages to them. It
is erroneous for client code to use such a session from another thread of
control. The only exception to this is the use of the session or connection close
method.
It should be natural for most clients to partition their work into sessions. This
model allows clients to start simply and incrementally add message processing
complexity as their need for concurrency grows.
4.4.7 Transactions
A Session may be optionally specified as transacted. Each transacted session
supports a single series of transactions. Each transaction groups a set of
produced messages and a set of consumed messages into an atomic unit of
work. In effect, transactions organize a sessions input message stream and
output message stream into series of atomic units. When a transaction
commits, its atomic unit of input is acknowledged and its associated atomic
unit of output is sent. If a transaction rollback is done, its produced messages
are destroyed and its consumed messages are automatically recovered. For
more information on session recovery see Section 4.4.13, Message
Acknowledgment
For Pub/Sub, if two sessions each have a subscriber that subscribes to the same
Topic, each Subscriber is given each message. Delivery to one Subscriber does
not block if the other gets behind.
For PTP, JMS does not specify the semantics of concurrent QueueReceivers for
the same queue; however, JMS does not prohibit a provider from supporting
this.
JMS does not define order of message receipt across destinations or across a
destinations messages sent from multiple sessions. This aspect of a sessions
input message stream order is timing dependent. It is not under application
control.
A sessions recover method is used to stop a session and restart it with its first
unacknowledged message. In effect, the sessions series of delivered messages
is reset to the point after its last acknowledged message. The messages it now
delivers may be different from that which were originally delivered due to
message expiration and the arrival of higher priority messages.
If a failure occurs between the time a client commits its work on a Session and
the commit method returns, the client cannot determine if the transaction was
committed or rolled back. The same ambiguity exists when a failure occurs
between the non-transactional send of a PERSISTENT message and the return
from the sending method.
For this reason, JMS does not cause concurrent execution of client code unless
a client explicitly requests it. One way this is done is to define that a session
serializes all asynchronous delivery of messages.
Note that JMS itself does not provide the facilities for concurrently processing
a topics message set (the messages delivered to a single consumer). A client
could use a single consumer and implement all the multi threading logic
needed to concurrently process them; however, it is not possible to reliably do
this because JMS does not have the transaction facilities needed to handle the
concurrent transactions this would require.
4.5 MessageConsumer
A client uses a MessageConsumer to receive messages from a destination. It is
created by passing a destination to a sessions createMessageConsumer method.
A consumer can be created with a message selector. This allows the client to
restrict the messages delivered to the consumer to those that match the
selector. See Section 3.8.1, Message Selector for more information.
JMS providers should flag clients with message listeners that are throwing
RuntimeExceptions as possibly malfunctioning.
See Section 4.4.16, Serial Execution of Client Code for information about how
onMessage calls are serialized by a session.
4.6 MessageProducer
A client uses a MessageProducer to send messages to a Destination. It is created
by passing a destination to a sessions createMessageProducer method.
A client can specify a default delivery mode, priority, and time-to-live for
messages sent by a producer. It can also specify delivery mode, priority, and
time-to-live per message.
The use of PERSISTENT messages does not guarantee that all messages are always
delivered to every eligible consumer. See Section 4.10, Reliability for further
discussion on this topic.
A JMS provider should do its best to accurately expire messages; however, JMS
does not define the accuracy provided. It is not acceptable to simply ignore
time-to-live.
4.9 Exceptions
JMSException is the base class for all JMS exceptions. See Chapter 7, JMS
Exceptions for more information.
4.10 Reliability
Most clients should use producers that produce PERSISTENT messages. This
insures once-and-only-once message delivery.
When this is done, applications have the highest level of assurance that a
message has been properly produced; reliably delivered; and, accurately
consumed. Non-transactional production and consumption can also achieve
the same level of assurance; however, this requires careful programming.
A JMS provider may have resource restrictions that limit the number of
messages that can be held for high volume destinations or non-responsive
clients. If messages are dropped due to resource limits this is usually a serious
administrative issue that needs attention. Correct functioning of JMS requires
5.1 Overview
Point-to-point systems are about working with queues of messages. They are
point-to-point in that a client sends a message to a specific queue. Some PTP
systems blur the distinction between PTP and Pub/Sub by providing system
clients that automatically distribute messages.
It is common for a client to have all its messages delivered to a single queue.
Like any generic mailbox, a queue can contain a mixture of messages. And, like
real mailboxes, creating and maintaining each queue is somewhat costly. Most
queues are created administratively and are treated as static resources by their
clients.
The JMS PTP model defines how a client works with queues. How it finds
them; how it sends messages to them; and, how it receives messages from
them.
68
5
5.3 Queue
A Queue object encapsulates a provider-specific queue name. It is the way a
client specifies the identity of queue to JMS methods.
The actual length of time messages are held by a queue and the consequences
of resource overflow are not defined by JMS.
See Section 4.2, Administered Objects for more information about JMS
Destination objects.
5.4 TemporaryQueue
A TemporaryQueue is a unique Queue object created for the duration of a
QueueConnection. It is a system defined queue that can only be consumed by
the QueueConnection that created it.
5.5 QueueConnectionFactory
A client uses a QueueConnectionFactory to create QueueConnections with a JMS
PTP provider.
See Section 4.2, Administered Objects for more information about JMS
ConnectionFactory objects.
5.6 QueueConnection
A QueueConnection is an active connection to a JMS PTP provider. A client uses
a QueueConnection to create one or more QueueSessions for producing and
consuming messages.
5.7 QueueSession
A QueueSession provides methods for creating QueueReceivers, QueueSenders,
QueueBrowsers and TemporaryQueues.
5.8 QueueReceiver
A client uses a QueueReceiver for receiving messages that have been delivered
to a queue.
Although is possible to have two sessions with a QueueReceiver for the same
queue, JMS does not define how messages are distributed between the
QueueReceivers.
5.9 QueueSender
A client uses a QueueSender to send messages to a queue.
5.10 QueueBrowser
A client uses a QueueBrowser to look at messages on a queue without removing
them.
Messages may be arriving and expiring while the scan is done. JMS does not
require the content of an enumeration to be a static snapshot of queue content.
Whether these changes are visible or not depends on the JMS provider.
5.11 QueueRequestor
JMS provides a QueueRequestor helper class to simplify making service
requests.
This is a basic request/reply abstraction that should be sufficient for most uses.
JMS providers and clients can create more sophisticated versions.
5.12 Reliability
A queue is typically created by an administrator and exists for a long time. It is
always available to hold messages sent to it whether or not the client that
consumes its messages is active. For this reason, a client does not have to take
any special precautions to insure it does not miss messages.
6.1 Overview
The JMS Pub/Sub model defines how JMS clients publish messages to, and
subscribe to messages from a well known node in a content based hierarchy.
JMS calls these nodes topics.
In this section, the terms publish and subscribe are used in place of the more
generic terms produce and consume used previously.
A topic can be thought of as a mini message broker that gathers and distributes
messages addressed to it. By relying on the topic as an intermediary, message
publishers are kept independent of subscribers and vice versa. The topic
automatically adapts as both publishers and subscribers come and go.
Publishers and subscribers are active when the Java objects that represent them
exist. JMS also supports the optional durability of subscribers that remembers
the existence of them while they are inactive.
For instance, some messages from a distant publisher may be missed because it
may take a second for the existence of a new subscriber to be propagated
72
6
system wide. When a new subscriber is created, it may receive messages sent
earlier because a provider may still have them available.
JMS does not define the exact semantics that apply during the interval when a
pub/sub provider is adjusting to a new client. JMS semantics only apply once
the provider has reached a steady state with respect to a new client.
All JMS providers must be able to run JMS applications that dynamically create
and delete durable subscriptions. Some JMS providers may, in addition,
provide facilities to administratively configure durable subscriptions. If a
durable subscription has been administratively configured it is valid for it to
silently override the subscription specified by the client.
An inactive durable subscription is one that exists but does not currently have a
message consumer subscribed to it.
JMS does not define facilities for creating, administering, or deleting topics.
6.5 Topic
A Topic object encapsulates a provider-specific topic name. It is the way a
client specifies the identity of a topic to JMS methods.
Many Pub/Sub providers group topics into hierarchies and provide various
options for subscribing to parts of the hierarchy. JMS places no restriction on
what a Topic object represents. It might be a leaf in a topic hierarchy or it might
be a larger part of the hierarchy (for subscribing to a general class of
information).
6.6 TemporaryTopic
A TemporaryTopic is a unique Topic object created for the duration of a
TopicConnection. It is a system defined Topic that can only be consumed by the
TopicConnection that created it.
6.7 TopicConnectionFactory
A client uses a TopicConnectionFactory to create TopicConnections with a JMS
Pub/Sub provider.
See Section 4.2, Administered Objects for more information about JMS
ConnectionFactorys.
6.8 TopicConnection
A TopicConnection is an active connection to a JMS Pub/Sub provider. A client
uses a TopicConnection to create one or more TopicSessions for producing and
consuming messages.
6.9 TopicSession
A TopicSession provides methods for creating TopicPublishers,
TopicSubscribers and TemporaryTopics. It also provides the unsubscribe
method for deleting its clients durable subscriptions.
6.10 TopicPublisher
A client uses a TopicPublisher for publishing messages on a topic. TopicPublisher
is the Pub/Sub variant of a JMS MessageProducer. See Section 4.6,
MessageProducer for a description of its common features.
6.11 TopicSubscriber
A client uses a TopicSubscriber for receiving messages that have been published
to a topic. TopicSubscriber is the Pub/Sub variant of a JMS MessageConsumer. For
more information see Section 4.5, MessageConsumer.
Regular TopicSubscribers are not durable. They only receive messages that are
published while they are active.
In some cases, a connection may both publish and subscribe to a topic. The
subscriber NoLocal attribute allows a subscriber to inhibit the delivery of
messages published by its own connection.
Sessions with durable subscribers must always provide the same client
identifier. In addition, each client must specify a name which uniquely
identifies (within client identifier) each durable subscription it creates. Only
one session at a time can have a TopicSubscriber for a particular durable
subscription. See Section 4.3.2, Client Identifier for more information.
The amount of resources allocated for message storage and the consequences
of resource overflow are not defined by JMS.
6.14 TopicRequestor
JMS provides a TopicRequestor helper class to simplify making service requests.
This is a basic request/reply abstraction that should be sufficient for most uses.
JMS providers and clients are free to create more sophisticated versions.
6.15 Reliability
When all messages for a topic must be received, a durable subscriber should be
used. JMS insures that messages published while a durable subscriber is
inactive are retained by JMS and delivered when the subscriber subsequently
becomes active.
7.1 Overview
This chapter provides an overview of JMS exception handling and defines the
standard JMS exceptions.
JMS methods only include JMSException in their signatures. JMS methods can
throw any JMS standard exception as well as any JMS provider specific
exception. The javadoc for JMS methods documents only the mandatory
exception cases.
78
7
There are only a few cases where JMS mandates that a specific JMS exception
must be thrown. These cases are indicated by the words must be in the
exception description. These cases are the only ones on which client logic
should depend on a specific problem resulting in a specific JMS exception being
thrown.
In the remainder of cases, it is strongly suggested that JMS providers use one
of the standard exceptions where possible. JMS providers may also derive
provider specific exceptions from these if needed.
8.1 Overview
This chapter describes JMS facilities for concurrent processing of a
subscriptions messages. It also defines how a JMS provider supplies JTS aware
sessions. These facilities can also be used by expert JMS clients.
These facilities are a special category of JMS. They will only be supported by
the more sophisticated JMS providers.
82
8
8.2.1 Session
Sessions provide three methods for use by application servers:
setMessageListener() and getMessageListener() - a sessions MessageListener
consumes messages that have been assigned to the session by a
ConnectionConsumer, see below.
run() - causes the messages assigned to its session by a ConnectionConsumer
to be serially processed by the sessions MessageListener. When the listener
returns from processing the last message, run() returns.
Since many listeners will need to use the services of its session, the listener is
likely to require that its session be passed to it as a constructor parameter.
8.2.2 ServerSession
A ServerSession is an object implemented by an application server. It is used by
an application server to associate a thread with a JMS session.
8.2.3 ServerSessionPool
A ServerSessionPool is an object implemented by an application server to
provide a pool of ServerSessions for processing the messages of a
ConnectionConsumer.
JMS does not architect how the pool is implemented. It could be a static pool of
ServerSessions or it could use a sophisticated algorithm to dynamically create
ServerSessions as needed.
8.2.4 ConnectionConsumer
For application servers, connections provide a special facility for creating a
ConnectionConsumer. The messages it is to consume are specified by a
destination and a message selector. In addition, a ConnectionConsumer must be
given a ServerSessionPool to use for processing its messages. A maxMessages
value is specified to limit the number of messages a ConnectionConsumer may
load at one time into a ServerSessions Session.
The JMS provider retains control of its messages until they are delivered to the
MessageListener. This insures it is under direct control of message
acknowledgment.
JMS App
Provider implements Server
ServerSession
implements controls
thread for
Manages a implements
pool of
implements
Session
delivers
messages
gets a ServerSessionPool
to
ServerSession
Connection from
Consumer delivers
messages
to
is delivered
messages for
Destination with
optional message Message
selector Listener
supplies implements
App
ServerSessionPool
getServerSession
Destination with
optional message
selector ServerSession
getSession
Session
start
ServerSession
run
Session
onMessage
Message
Listener
8.3 XAConnectionFactory
Some application servers provide support for grouping resource use into a
distributed transaction. To include JMS transactions in a distributed
transaction, an application server requires a Java Transaction API (JTA) capable
JMS provider. A JMS provider exposes its JTA support using a JMS
XAConnectionFactory which an application server uses to create XAConnections.
8.4 XAConnection
XAConnection extends the capability of Connection by providing the ability to
create XASessions.
8.5 XASession
XASession provides access to what looks like a normal Session object and a
javax.transaction.xa.XAResource object which controls the sessions transaction
context. The functionality of XAResource closely resembles that defined by the
standard X/Open XA Resource interface.
A client of the application server is given the XASessions Session. Behind the
scenes, the application server controls the transaction management of the
underlying XASession.
9.1.1 Background
The following code examples show several ways a client could use the various
JMS API message types with both the Point-to-Point and Publish/Subscribe
messaging, to obtain stock quote information.
Note that no exception handling code is included. This makes it easier to see
what's happening.
Lets assume that there is a stock quote service which sends out the stock quote
messages. This could be done in many different ways, and as will be shown
below, the construction of these messages is the same for both PTP and
Pub/Sub messaging.
Before we can send and receive message, the client application needs to do
some initial setup.
90
9
queueConnectionFactory = (QueueConnectionFactory)
messaging.lookup(QueueConnectionFactory);
queueConnection = queueConnectionFactory.createQueueConnection();
QueueSession session;
session = queueConnection.createQueueSession(false,
Session.AUTO_ACKNOWLEDGE);
QueueSender sender;
sender = session.createSender(queue);
QueueReceiver receiver;
receiver = session.createReceiver(queue);
topicConnectionFactory = (TopicConnectionFactory)
messaging.lookup("TopicConnectionFactory");
Topic stockTopic;
topicConnection = topicConnectionFactory.createTopicConnection();
session = topicConnection.createTopicSession(false,
Session.CLIENT_ACKNOWLEDGE);
TopicSubscriber subscriber;
subscriber = session.createSubscriber(stockTopic);
Our listener class (lets call it StockListener.java) would look something like:
void
onMessage(Message message) {
}
}
StockListener myListener;
subscriber.setMessageListener(myListener);
TopicPublisher publisher;
publisher = session.createPublisher(stockTopic);
message = session.createByteMessage();
message.writeBytes(stockData);
message = session.createTextMessage();
message.setText(stockData);
The client would receive the whole map message, but might only be interested
in displaying part of this information. It could extract the required fields from
the message, ignoring the rest.
message = session.createMapMessage();
message.setString("Name", stockName);
message.setDouble("Value", stockValue);
message.setLong("Time", stockTime);
message.setDouble("Diff", stockDiff);
message.setString("Info", stockInfo);
The client might be only interested in some of the message field, but in the case
of a stream message, it has to read (and potentially throw away) each field in
turn.
message = session.createStreamMessage();
Note that the following have to be written in the order they will be read.
message.writeString(stockName);
message.writeDouble(stockValue);
message.writeLong(stockTime);
message.writeDouble(stockDiff);
message.writeString(stockInfo);
These values could have been passed in when the stock object was constructed.
stockObject.setName(stockName);
stockObject.setValue(stockValue);
stockObject.setTime(stockTime);
stockObject.setDiff(stockDiff);
stockObject.setInfo(stockInfo);
message = session.createObjectMessage();
message.setObject(stockObject);
sender.send(message);
StreamMessage stockMessage;
stockMessage = (StreamMessage)receiver.receive();
publisher.publish(message);
void
onMessage(Message message) {
length = message.readBytes(stockData);
stockData = message.getText();
stockName = message.getString("Name");
stockValue = message.getDouble("Value");
stockTime = message.getLong("Time");
stockDiff = message.getDouble("Diff");
stockInfo = message.getString("Info");
stockName = message.readString();
stockValue = message.readDouble();
stockTime = message.readLong();
stockDiff = message.readDouble();
stockInfo = message.readString();
stockObject = message.getObject();
stockName = stockObject.getName();
stockValue = stockObject.getValue();
stockTime = stockObject.getTime();
stockDiff = stockObject.getDiff();
stockInfo = stockObject.getInfo();
String selector;
QueueReceiver receiver;
TopicSubscriber subscriber;
Now we will only receive the stock quotes we are interested in.
10.1.3 Should the Two JMS Domains, PTP and Pub/Sub, be merged?
Even though there are many similarities, providing separate domains still seem
to be important.
It means that vendors aren't forced to support facilities out of their domain and
client code can be a bit more portable because products more fully support a
domain (as opposed to supporting less defined subsets of a merged domain).
102
10
Java technology is well integrated with CORBA. It provides Java IDL and COS
Naming. In addition, OMG has recently defined RMI over IIOP.
It is expected that most use of IIOP from Java will be via RMI. It is expected
that most use of COS Naming from Java with be via JNDI (Java Naming and
Directory Service). JMS is a Java specific API designed to be layered over a
wide range of existing and future MOM systems (just like JNDI is layered over
existing name and directory services).
The benefit of send-to-list is slightly less work for the programmer and the
potential for the JMS provider to optimize the fact that several destinations are
being sent the same message.
The down side of a send-to-list mechanism is that the list is, in effect, a group
that is implemented and maintained by the client. This would complicate the
administration of JMS clients.
106
11
was better handled in the same way that overlapping subscriptions from
different sessions are treated, so this special case has been removed.
JMS 1.0.1 was ambiguous about whether or not calls to connection and session
close returned immediately. Connection and session close now explicitly state
that they block until message processing has been orderly shutdown.
The close sequence of TopicRequestor and QueueRequestor did not agree with
the order specified in the specification and this has been corrected.
Note that the InvalidClientIDException is used for any client id value that a JMS
provider considers invalid. Since client id value is JMS provider specific the
criteria for determining a valid value is provider specific.
A note has been added that clarifies when setClientID method of Connection
should be used.
Note that the unsubscribe method of TopicSession should not be called to delete
a durable subscription if there is a TopicConsumer currently consuming it.
Note that the setObject method of ObjectMessage places a copy of the input
object in a message.
Note that a connection is created in stopped mode and, for incoming messages
to be delivered to the message listeners of its sessions, its start method must be
called.
Note the result of readBytes method of StreamMessage when the callers byte[]
buffer is smaller than the byte[] field value being read.