IBM Skip to main content
Search for:   within 
      Search help  
     IBM home  |  Products & services  |  Support & downloads   |  My account

developerWorks > Java technology
developerWorks
J2EE pathfinder: Enterprise messaging with JMS
Discuss85 KBe-mail it!
Contents:
Enterprise messaging 101
Java Message Service
Simple JMS client
Session beans and JMS
Message-driven beans
Messaging solution guidelines
Conclusion
Resources
About the author
Rate this article
Related content:
J2EE pathfinder series
The ABCs of EJBs
Introducing the Java Message service
Vendor-neutral JMS
JMS for data replication
Subscriptions:
dW newsletters
dW Subscription
(CDs and downloads)
J2EE messaging solutions for your enterprise

Level: Intermediate

Kyle Gabhart (mailto:kyle@gabhart.com?cc=&subject=Enterprise messaging with JMS)
Consultant, Gabhart Consulting
24 June 2003

Column iconIn this installment of J2EE pathfinder, Java developer and consultant Kyle Gabhart explains why a messaging service is essential to your enterprise architecture, what kind of obstacles your solution must overcome, and what alternatives you have under the Java Message Service (JMS). At the end of the article, he breaks down the three available solutions (a simple JMS client, session beans combined with JMS, or message-driven beans), and offers some specific guidelines for weighing the options. Share your thoughts on this article with the author and other readers in the accompanying discussion forum. (You can also click Discuss at the top or bottom of the article to access the forum.)

When it comes to choosing a messaging solution, you're looking for the one that fits your enterprise like a glove. Your messaging framework must be able to communicate across an array of applications and enterprise resources. It must do so quickly and reliably. And it must perform seamlessly in the face of both day-to-day hassles and emergencies.

To choose the right messaging solution for your needs, it helps to have a good picture of both your current enterprise makeup and where it's headed in the future. It also helps to completely understand the obstacles a messaging framework must overcome in order to fulfill its goals. And finally, you want to know what's out there: what technologies are available and how each one is individually suited to different environments and needs.

In this installment of J2EE pathfinder, we'll address each of these points. We'll start with an overview of enterprise messaging, where we'll look at the role of messaging in your enterprise, as well as some of the challenges in establishing reliable communication. Next, we'll take an architectural view, with a quick look at how J2EE messaging technologies work together with message-oriented middleware in a typical enterprise network. From there, we'll move into a more specific discussion of the Java Message Service (JMS), J2EE's messaging package. We'll review the basic goals and functions of each of the three types of J2EE messaging clients and you'll get an idea of where each one shines, and where it falls short. We'll close with a breakdown of common messaging scenarios and solutions, which will help you choose the best J2EE messaging solution for your enterprise.

Enterprise messaging 101
Enterprise messaging frameworks are designed to enable one or more applications to communicate despite a variety of obstacles. Common barriers include the requirement that both systems be running at the same time (synchronous communication), the need for multiple applications to receive the same message (multiple transmissions), the heterogeneity of most systems, and network failure.

Many enterprise architectures rely on message-oriented-middleware systems (MOMs) to channel messages between disparate systems. MOMs provide a common and reliable way for applications to create, exchange, and process messages without regard for the implementation details of the messaging client. Messages are sent to server destinations and domains rather than physical addresses. Messaging clients simply declare interest in a particular domain and destination, provide the proper security tokens to gain access to the domain in question, and then interact with the messaging server through that destination.

Conceptually, this is no different from the way that physical mail is delivered in real life. The sender of a message is responsible only for using the correct packaging, supplying an accurate address, and applying the appropriate postage. The postal service (in our case, a MOM system) handles all issues related to the secure and reliable delivery of the message regardless of any obstacles that present themselves (mechanical failures, bad weather, etc.).

In a MOM system, clients are decoupled from one another, allowing them to maintain optimum quality of service without actually having to be "online" every second of the day. After you've removed the requirement that applications be always available, maintenance and scalability are much easier to manage. Applications can be brought down, updated, or refreshed for routine maintenance at almost any time of day, without affecting quality of service.

Java Message Service
MOM servers allow disparate systems to exchange messages, but each MOM vendor has a proprietary API for handling messages. This lack of standardization is unacceptable in the Java technology development paradigm. To take advantage of the already existing infrastructure of MOMs without sacrificing standardization, the J2EE platform offers JMS.

Java standardization
In order to provide platform- and vendor-neutral solutions, all Java technologies come in two essential pieces:

  1. A specification (or set of specifications) that defines the technology, identifying its objectives and the responsibilities of developers and tool vendors that implement it.

  2. A set of neutral interfaces that serve as a contract between application developers and tool vendors.

No matter what Java technology you are using, you will first write application components that utilize the technology specification's interfaces, and then supply a particular vendor's implementation of those interfaces at run time. In J2EE, the enterprise messaging specification and API are JMS.

JMS defines the rules for message delivery in Java enterprise systems, and also declares interfaces to facilitate message exchange between application components and messaging systems (typically MOMs). JMS clients open connections to destinations on the MOM server and then send and receive messages on those destinations. JMS offloads the responsibilities of guaranteed delivery, message notification, message durability, and all of the underlying networking and routing issues to the messaging system. JMS and MOMs work nicely together because they both divide responsibility between message clients and the messaging server.

Types of messaging
JMS supports two fundamental messaging mechanisms. The first is point-to-point messaging, in which a message is sent by one publisher (sender) and received by one subscriber (receiver). The second is publish-subscribe messaging, in which a message is sent by one or more publishers and received by one or more subscribers. While these two mechanisms are the actual foundation of JMS, many view the technology in terms of its three messaging models:

  • One-to-one messaging is a point-to-point model. A message is sent from one JMS client (publisher) to a destination on the server known as a queue. Another JMS client (subscriber) can access the queue and retrieve the message from the server. Multiple messages may reside on the queue, but each message is removed upon retrieval.

  • One-to-many messaging is a publish-subscribe model. A JMS client still publishes a message to a destination on the server, but the destination is now referred to as a topic. The key difference here is that messages placed in a topic include a parameter that defines the message durability (how long it should remain on the server awaiting subscribers). The message will remain on the topic until all subscribers to the topic have retrieved a copy of the message or until its durability has expired, whichever comes first.

  • Many-to-many messaging, also a publish-subscribe model, extends one-to-many messaging. In addition to supporting multiple subscribers, this model also supports multiple publishers on the same topic. A good example of many-to-many messaging would be an e-mail listserve: multiple publishers can post messages on a topic, and all subscribers will receive each message.

The structure of a JMS message is fairly intuitive. There is a section for routing, addressing, and message identification; an optional section where application-specific parameters can be passed; and a third section where the message payload (text, bytes, value map, object, etc.) is stored. These three sections are known as the header, property, and body, as illustrated in Figure 1.

Figure 1. JMS message structure
JMS message structure

The type of messaging model you employ depends upon the needs of your enterprise. It is not uncommon to employ more than one messaging strategy within a single enterprise. In the sections that follow, we will explore three JMS solutions for the Java platform: the simple JMS client, session beans combined with JMS, and message-driven beans. We'll review each type, its pros and cons, and its applicability to different enterprise scenarios.

Simple JMS client
Although JMS is an enterprise-grade technology shipped with the Java 2 Enterprise Edition, you can easily transform a standard Java client into a JMS-capable application. Adding enterprise messaging capabilities to a Java applet, command-line application, Swing application, or Java WebStart client is fairly simple. You simply add a handful of method calls to your J2SE application code, and then add a single JAR file to your classpath containing the interfaces and implementation classes for JNDI (also part of J2EE). After you've loaded the JAR file on your client machine and added it to your application's classpath, you can use JNDI to access a JMS provider (see Resources below for links to more information on JMS messaging).

Simple JMS client pros and cons
The simple JMS client approach has many advantages, the most obvious being its simplicity and ubiquity. Absolutely any J2SE application can be extended to interface with a JMS messaging system with minimal effort. In addition, new applications that utilize JMS can be deployed with a little or no client-side configuration necessary. The simple JMS client is a simple, flexible, and lightweight extension to almost any Java architecture.

On the downside, we have issues of security, transaction handling, and scalability. In the case of a simple JMS client, you often have no choice but to outsource security and transaction handling to a provider, which means they will be handled in a vendor-specific way. Scalability becomes an issue if your simple JMS client needs to process incoming messages as well as to send messages. JMS has no built-in mechanism to handle more than one incoming request at a time. To support concurrent requests, you will need to extend the JMS client to spawn multiple threads, or launch multiple JVM instances, each running the application. In addition, the JMS provider will need to be configured to support multiple subscribers on the appropriate destinations. At that point, you (or your development team) may question the actual simplicity of the simple JMS client solution.

Session beans and JMS
Combining session beans and JMS is a sensible enterprise-oriented solution. Session beans are designed to fulfill requests for business services. To the extent that an enterprise messaging system must be queried to fulfill such a request, it can be accessed transparently via a session bean. Using a session bean as your JMS client also allows the JMS communication to be incorporated into the context of a larger business transaction. For example, a J2EE transaction could be set to retrieve a message from a JMS provider, extract data from that message, and then attempt to update the database. If the update failed and the transaction rolled back, another message could be sent to the JMS provider on a separate destination, describing the reason for the failed transaction.

Enterprise JavaBeans technology uses resource manager connection factories to access extra-container resources. The resources are standard enterprise components that are not a core part of a J2EE container, including data sources, JMS sessions, JavaMail sessions, URL connections, and Java Connector Architecture (JCA) adapters. A resource manager is a component of a J2EE container that manages the entire lifecycle of a particular type of resource, including connection pooling, transaction support, and any necessary network protocols that make the actual connection possible.

Three steps enable your enterprise bean to obtain a connection to a JMS session: a JNDI lookup obtains a connection-factory reference, a connection is obtained via the factory reference, and the topic or queue connection object is used in the normal fashion for JMS. Because JMS must be supported by any J2EE-compliant application server, no additional libraries or components are required.

JMS-session bean pros and cons
Combining JMS and session beans is a step forward in terms of enterprise functionality, but a step backward in terms of simplicity and flexibility. Using session beans provides the application developer access to the full range of J2EE functionality afforded by the EJB container, including JNDI, declarative transaction semantics, automatic concurrency support and resource management, declarative security, and access to other enterprise resources such as entity beans, datasources, JavaMail, and JCA adapters. From a messaging standpoint (unlike MDBs), the session bean-JMS combination imposes no limit on the number of topics and queues that your bean can access.

In exchange for enhanced enterprise features, you sacrifice simplicity, a small client footprint, and asynchrony. The first two should come as no surprise, especially if you've been following the Pathfinder series for a while. Session beans require a full-blown J2EE EJB container, which puts a significant burden on both your development team (in terms of EJB development) and your overall system architecture (in terms of client footprint).

Asynchrony is one of the major advantages of using an enterprise messaging technology like JMS, and losing it is no small thing. With JMS, messaging clients can send messages via the provider and then go offline, leaving the provider to transmit the message as time allows. Receiving clients can either log on periodically and check for new messages or set up a listener component that is always online awaiting new messages from the provider. Session beans are synchronous, and so cannot support the "always-on" listener component. Instead, a synchronous Java client must invoke a session bean method. The session bean method then opens a connection with a messaging provider to send and receive messages.

Message-driven beans
The EJB 2.0 specification defines a new type of enterprise bean to complement the other four types available (two session types and two entity types). The new bean type, message-driven beans (MDBs), is intended to provide a reusable J2EE messaging component that can leverage existing investments in J2EE application servers, and EJB technology specifically.

MDBs are only intended to be invoked asynchronously through a JMS message. As such, they do not have the traditional home and remote interfaces that other enterprise beans do. Instead, they implement two special interfaces: an interface to the EJB container (javax.ejb.MessageDrivenBean), and a messaging interface (javax.jms.MessageListener). As a full-fledged JMS client, MDBs can both send and receive messages asynchronously via a MOM server. As an enterprise bean, MDBs are managed by the container and declaratively configured by an EJB deployment descriptor.

MDB pros and cons
MDBs allow developers to leverage an existing investment in EJB technology while still integrating that technology into an asynchronous messaging context. For instance, a JMS client could send a message to an MDB (which is constantly online awaiting incoming messages), which in turn could access a session bean or a handful of entity beans. In this way, MDBs can be used as a sort of an asynchronous wrapper, providing access to business processes that could previously be accessed only via a synchronous RMI/IIOP call.

Message-driven beans are also a powerful messaging solution on their own. Because they are specifically designed as message consumers and yet are still managed by the EJB container, MDBs offer a tremendous advantage in terms of scalability. Because message beans are stateless and managed by the container, they can both send and receive messages concurrently (the container simply grabs another bean out of the pool). This, combined with the inherent scalability of EJB application servers, produces a very robust and scalable enterprise messaging solution.

On the other hand, MDBs are relatively new and untried. Consequently, not all J2EE vendors support them, and those that do have only recently implemented them. As is to be expected, the immaturity of MDB solutions means that vendor implementations still have a ways to go in terms of stability and reliability. Also, the community has yet to hammer out a solid set of best practices for using MDBs.

Moving beyond the relative immaturity of message beans, it is important to understand that they are designed for a very specific purpose, as a consumer of JMS messages. They cannot be invoked in any manner other than via a JMS message. This means that they are ideally suited as message consumers, but not necessarily as message producers. Message-driven beans can certainly send messages, but only after first being invoked by an incoming request. Also, MDBs are currently designed to map to only a single JMS destination. They listen for messages on that destination only. This could change in a later version, but currently you must define an MDB for each destination that you want to listen on.

Messaging solution guidelines
As previously mentioned, a big part of choosing the right solution is weighing the specific needs of your enterprise, both in the present and in the foreseeable future. It is also helpful to remember that enterprise messaging solutions can be combined. In the section that follows, we'll see a few common messaging scenarios and the potential JMS solutions for each one. They will give you some general guidelines for determining the right messaging technology, or mix of technologies, for your enterprise.

Access multiple topics and queues from one component
If your business process dictates that message destinations should be accessed conditionally (in other words, if x<5, access topic A, else if x>5, access topic B), then you won't be able to use MDBs. You can, however, use a simple JMS client, or combine session beans and JMS. To decide between the two options, you must weigh the lightweight nature of the simple JMS client (perfect for applets, Swing apps, and stand-alone console applications) versus the robustness of a J2EE container (complete with transparent transactional support, declarative security, and other EJB-style resource-management features).

Access session and entity beans asynchronously
There are two ways to handle this scenario. The obvious one is to use a message-driven bean, but only if your vendor supports MDB technology. MDBs are designed to consume asynchronous messages and access enterprise functionality on behalf of the message sender. Additionally, application servers can maintain multiple instances of an MDB to handle concurrent service requests. If you can't use an MDB, then you can create a simple JMS client to serve as a listener. Upon receiving a message, the client could then establish a synchronous RMI connection with the application server and invoke the session or entity beans in the usual way. MDBs would be the preferred solution, however.

Build the thinnest possible JMS client
The simple JMS client is clearly the winner here. If it is more important to you to provide a lightweight messaging client than to have the scalability and robustness of a J2EE client such as a session bean, then the simple JMS client is the right choice. Both the session bean-JMS combination and MDBs require a J2EE application server, making neither choice suitable for thin-client implementations.

Concurrently send and receive messages
The only real option here is to use message-driven beans. They are specifically tailored to support this very scenario. Technically, a simple JMS client could be multithreaded to provide similar support, but the development for such a solution would be complicated, and wouldn't yield an especially scalable result.

Incorporate messaging into J2EE processes
You may have already invested in a J2EE architecture, only to recognize the need to incorporate enterprise messaging into these processes. In most cases, your best solution will be to combine session beans with a JMS resource connection. Rather than rebuild your entire infrastructure, you can adapt existing session beans to access one or more topics and queues. The beans will continue to fulfill traditional requests for business services, and also take on the task of messaging. In some cases, it may be beneficial to expose your existing business services to a JMS client, as discussed above.

Conclusion
Enterprise messaging is an exciting and increasingly popular solution to the heterogeneous and increasingly asynchronous nature of today's technical landscape. The Java Message Service provides a vendor- and platform-independent medium for tying systems together with enterprise messaging. In this article, we've briefly explored enterprise messaging and JMS, and I've given you some guidelines for choosing the one most appropriate for your enterprise.

Resources

About the author
Photo of Kyle GabhartKyle Gabhart is an independent consultant and subject matter expert with J2EE, XML, and Web services technologies. Kyle is a popular public speaker, recognized for his enthusiasm and dynamic analysis and presentation of emerging technologies. For information on his recent and upcoming presentations or industry publications, visit Gabhart.com. Kyle can be reached at kyle@gabhart.com.


Discuss85 KBe-mail it!

What do you think of this document?
Killer! (5) Good stuff (4) So-so; not bad (3) Needs work (2) Lame! (1)

Send us your comments or click Discuss to share your comments with others.



developerWorks > Java technology
developerWorks
  About IBM  |  Privacy  |  Terms of use  |  Contact