J2EE messaging solutions for your enterprise
messaging with JMS)
Consultant, Gabhart Consulting
In 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
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 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.
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.
In order to
provide platform- and vendor-neutral solutions, all Java
technologies come in two essential pieces:
- A specification (or set of specifications) that defines
the technology, identifying its objectives and the
responsibilities of developers and tool vendors that implement
- 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 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
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
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
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
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
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
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
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
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.
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
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
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
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.
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
Access session and entity beans
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
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
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
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.
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.
Kyle 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 email@example.com.