Skip to main content

skip to main content

developerWorks  >  Java technology  >

JMS 1.1 simplifies messaging with unified domains

Learn how the new API will help you write more reusable JMS clients

developerWorks
Document options

Document options requiring JavaScript are not displayed

Sample code


Rate this page

Help us improve this content


Level: Intermediate

Bobby Woolf (woolf@acm.org), Independent consultant, Cyberdyne Software, Inc.

01 Aug 2002

JMS forms the foundation of messaging in enterprise Java applications, but has always treated point-to-point messaging and publish/subscribe messaging as completely separate domains with distinctly different types of messaging destinations. The JMS 1.0.2 API provides little support for an application using both domains together, and no support for developing reusable frameworks that can work equally well with destinations of either domain. JMS 1.1 fixes this shortcoming by unifying these domains. Join Bobby Woolf, J2EE architect and author, as he explores how much easier it is to develop JMS client code using the latest version.

The Java Message Service (JMS) API is an integral element of the J2EE platform. JMS 1.0.2 defines two separate types of messaging domains, point-to-point and publish/subscribe. The latest version of JMS, version 1.1, which will be part of J2EE 1.4 and will be required by EJB 2.1, unifies these domains. With JMS 1.1, a client no longer has to be implemented specifically for one domain or the other. Instead, JMS clients can be implemented to work with destinations from either domain. This significantly simplifies the JMS API and offers developers an opportunity to create more general, reusable messaging code. Once JMS providers and J2EE containers that implement JMS 1.1 become available, developers of JMS client code should start using the version 1.1 APIs in their new code, and may also benefit from porting their existing JMS 1.0.2 code to the new APIs.

We'll be jumping directly into the new spec, so if you need a refresher on JMS, see A quick introduction to JMS.

Three sets of interfaces

In JMS 1.0.2, the three channel interfaces -- Destination, Queue, and Topic -- have the unfortunate consequence of tripling the number of interfaces in the API. To send or receive messages, a client uses a connection factory to get a connection, which it uses to create a session and obtain message producers and consumers on the desired queues and topics. The only problem is that each kind of destination has its own factory, connection, session, producer, and consumer interfaces (basically, its own domain of interfaces), as summarized in Table 1 (from the JMS Javadocs).

Table 1. Relationship of point-to-point and publish/subscribe interfaces

JMS CommonPTP DomainPub/Sub Domain
ConnectionFactoryQueueConnectionFactoryTopicConnectionFactory
ConnectionQueueConnectionTopicConnection
DestinationQueueTopic
SessionQueueSessionTopicSession
MessageProducerQueueSenderTopicPublisher
MessageConsumerQueueReceiverTopicSubscriber

Furthermore, JMS provides another set of interfaces for compatibility with XA (distributed) transactions. This means that besides the 18 interfaces shown in the table, JMS has yet another nine interfaces -- XA versions of the factory, connection, and session types -- three times as many types as are really needed.

Industry support for JMS 1.1

The next major release of the Java 2 Platform, Enterprise Edition (J2EE 1.4; currently in public draft status) will include JMS 1.1, so J2EE containers (application servers) such as IBM WebSphere and BEA WebLogic will need to implement JMS 1.1 to be certified as J2EE 1.4 compatible. Likewise, the next version of the Enterprise JavaBeans spec (EJB 2.1; also currently public draft status) will require JMS 1.1 to support its JMS message-driven beans. And J2EE 1.4 will include EJB 2.1, so those specs and JMS 1.1 all go together.

A number of products implement JMS 1.0.2, but what about support for JMS 1.1 or intentions to implement it?

Two commercial messaging systems (AshnaMQ 2.1 and the Sun ONE Message Queue, Platform Edition 3.0) and one open source messaging system (JORAM 3.1.0) currently implement JMS 1.1, but none of the other JMS/J2EE vendors, including IBM, BEA Systems, TIBCO Software, and Sonic Software, have announced plans to support JMS 1.1 in future releases of their products. Considering all these companies currently support either JMS 1.0.2 or J2EE 1.2 or 1.3, it seems to be just a matter of time before JMS 1.1 support is offered.

Of those 27 interfaces, only the six common interfaces (those in the first column) are truly needed to send and receive messages. Queue and Topic are sometimes useful for distinguishing the point-to-point and publish/subscribe approaches. The other ten interfaces in the table and at least six of the nine XA interfaces are not really needed, at least not for writing client code.

For example, with JMS 1.0.2, if a developer were accessing a Queue, he would use a QueueConnectionFactory to get a QueueConnection, to create a QueueSession, which is used to create a QueueSender or QueueReceiver. But this code is queue-specific and will not work with a Topic. This approach will also work in JMS 1.1, but it is simpler to just use ConnectionFactory, Connection, Session, and MessageProducer or MessageConsumer, which will also work with a Topic just as well as a Queue. So the developer should use the common interfaces and avoid the domain-specific ones, because the common interfaces make the code simpler, more generic, and more reusable.

Non-unified interfaces

In JMS 1.0.2, client code must use the queue and topic domain-specific interfaces. The common interfaces are largely ceremonial and do not declare many of the methods clients need. For example: Destination implements no methods at all; MessageProducer does not implement a send method; MessageConsumer does implement receive, but a Session client cannot create a MessageConsumer; and so on.

Thus, for a client to send and receive messages on a Queue, it has to use the classes in the second column of Table 1, whereas a similar client using a Topic has to implement very similar code using the classes from the third column of Table 1. This lack of polymorphism among the common interfaces makes it impossible to reuse queue clients with topics and vice versa, which leads to the kind of duplicate code shown in Listing 1.



Back to top


Domain unification

The major change in JMS 1.1 is the addition of new APIs to support client code that works simultaneously with either the point-to-point or publish/subscribe domains. Specifically, the latest release adds methods to the common interfaces to make the queue and topic extensions polymorphic.

For example, MessageProducer now implements send, so a client can send a message to a destination without knowing whether the destination is a queue or a topic. Likewise, MessageConsumer declares the receive method so that the same client code works whether it's using an implementation of a queue receiver or a topic subscriber.

Listing 2 shows how to get a producer and consumer using this unified interface. The JMS 1.0.2 code, shown in Listing 1, required four methods (one pair for queues and another for topics) whereas the JMS 1.1 code only requires two methods (one pair for destinations).

These new APIs enable the developer to write JMS client code that is much more reusable. It simply accesses destinations and uses them without needing to know which destinations are queues and which are topics. Code written to access a queue can also be reused, unchanged, to access a topic in the same way, and vice versa. This was not possible with JMS 1.0.2.

Because the common interfaces are now able to perform almost all of the same tasks as their domain-specific extensions (for example, MessageProducer can do just about everything QueueSender and TopicPublisher can), the domain-specific subinterfaces are really no longer needed. These interfaces will probably be deprecated in future versions of JMS.

Shared transactions

A subtle but significant consequence of unifying the messaging domains is that queues and topics can now be accessed through the same session and thus in the same transaction. In JMS 1.0.2, a QueueSession could access more than one Queue, and a TopicSession could access multiple Topics, but a single session could not access both queues and topics. Because sessions manage transactions, a single transaction could not be used to control both a queue and a topic.

In JMS 1.1, not only can a single Session access either a Queue or a Topic (either kind of Destination), a single session instance can be used to manipulate one or more queues and one or more topics, all in a single transaction. This means that a single session can, for example, create producers on both a queue and a topic, and then use a single transaction to simultaneously send messages on both. Because of the single transaction spanning both destinations, either the queue's message and the topic's message both get sent, or neither of the messages gets sent. Likewise, a single transaction can be used to receive a message on a queue and send it on a topic, or vice versa, as shown in Listing 3.

Consider a customer tracking application providing information to other applications that use customer information, one of which is a shipping application. The tracking application may need to tell the other applications that a particular customer's address has changed. If using messaging, the application would publish this change on a topic, CustomerChanges, and all of the applications that use customer information would subscribe to this topic. The customer tracking application may want each subscriber to report back whether it was able to process the change successfully. It would specify a queue, ChangeProcessed, that each subscriber application would use to send a reply.

A subscriber application, such as the shipping application, would receive a change message on the CustomerChanges topic, process it, and send a reply on the ChangeProcessed queue. To ensure that no changes are lost, these three steps (receive request, process request, and send reply) should be performed in a single atomic transaction. This means that the shipping application must access both the CustomerChanges topic and the ChangeProcessed queue using the same session. A session cannot access both a topic and a queue in JMS 1.0.2, but can do so in JMS 1.1.



Back to top


Conclusions

JMS 1.0.2 suffers from an explosion of subtypes; for each type, there is an interface for the type itself, a queue extension, and a topic extension. Three times as many interfaces means three times as many APIs for developers to learn. Client code has to use one domain or the other, either the queue or topic set of extensions, so code written for one cannot be used for the other.

JMS 1.1 unifies the domains so that each common interface can be used instead of its domain-specific extensions. This means there are fewer interfaces for developers to learn, and the same client code can be used for both queues and topics. Furthermore, a JMS transaction can now more easily span a topic and a queue, something that was not possible until the domains were unified.

The unified API in JMS 1.1 makes JMS client code simpler, easier to maintain, and more reusable. Once vendors of JMS providers and J2EE containers implement JMS 1.1, developers writing new client code should definitely use the unified APIs. While old client code written for JMS 1.0.2 will still work fine in JMS 1.1, it may well be worth porting that code to the unified APIs to make it simpler, too.




Back to top


Download

NameSizeDownload method
j-jms11src.zipHTTP
Information about download methods


Resources



About the author

Photo of Bobby Woolf

Bobby Woolf is a J2EE architect and developer, author and speaker, mentor and mentee, and works as an independent consultant in Raleigh, North Carolina. He has used just about every part of the JMS client API: queues and topics, messages delivered synchronously and asynchronously, sessions transacted and non-transacted. He even experimented with temporary queues once, but he didn't like them very much. Contact Bobby at woolf@acm.org.




Rate this page


Please take a moment to complete this form to help us better serve you.



 


 


Not
useful
Extremely
useful
 


Share this....

digg Digg this story del.icio.us del.icio.us Slashdot Slashdot it!



Back to top