Message Driven Beans:
by Benoy Jose
Introduction:
Message Driven Beans were introduced in
the EJB 2.0 specification to accommodate the growing popularity of asynchronous
messaging. The driving factor for the popularity has been the wide spread use
of JMS based messaging systems, hence a brief intro on JMS would help
understand the concepts of MDB's. Message driven beans are a combination of
Session beans and JMS clients.
JMS Intro:
Different types of messaging
systems are present in the market to cater to different messaging needs and
platforms. The JMS specification was Sun's way of standardizing the
different types of java messaging systems present in the market.
The JMS Specification provides a unified API for using
Messaging systems while the details of implementing the Messaging service is
left to the individual vendors. There are a few major vendors like Websphere
MQ, Weblogic JMS Service, and Progress SonicMQ who provide Messaging services based
on the JMS API.
To implement JMS messaging we need a JMS Provider
which would be one of the implementations of Messaging provided by the vendors
discussed above. We also need JMS clients that use the messaging system. The
clients can be Message Producers or Message Consumers. The producers identify
the consumers by a Destination object. To sum the whole process "A Message
Producer uses a JMS provider to create a Message with a Destination address on
it and the Message will be consumed by a Message Consumer that has the
Destination address."
JMS defines two ways in which a message can be
sent to consumers. The first one is Publish-and-Subscribe where a single
Message Producer can send a message to many Message Consumers. The system uses
a channel called 'Topic' to publish the message and the message is broadcast to
all Message Consumers that are subscribed to the topic.
The second one is Point-To-Point (PTP) messaging where
clients can send and receive messages synchronously and asynchronously through
channels called queues. There could be multiple consumers attached to a queue
but the message is delivered only to the one consumer it was intended.
In both the systems discussed above the
'Message' is the central part. It contains the data that needs to be
transferred between the clients. JMS presently supports five types of messages.
They are TextMessage, ObjectMessage, MapMessage, BytesMessage, and StreamMessage. A
'TextMessage' holds a simple string message. An 'ObjectMessage' allows java
objects to be stored as part of a message. The 'MapMessage' allows us to store
data as key value pairs. The 'BytesMessage' and 'StreamMessage' allow us to
send a message as a stream of bytes and stream of primitives respectively.
MDB Intro
Message driven beans are enterprise beans
that act as message consumers in the messaging system. What makes MDB's
different from other JMS clients that can act as message consumers is its
ability to take care of important aspects like security, concurrency,
transaction etc. Conventional message consumers are java client programs that
have logic for consuming and processing the message. They also need to have the
intelligence to take care of security and concurrency. The client program is
usually a java program that waits for a message to be delivered by the message
producer. Sometimes they could wait indefinitely on messages which may lead to
valuable resources being held up. The solution to this is to have clients to
poll frequently for a message or wait for a message and if no message is
received, time out the request.
All of the factors above make Message driven beans an
ideal choice for message consumers. Though the Message driven bean is part of
the EJB2.0 family it does not share the common features of its brothers the
session bean and the entity bean. A MDB combines the flexibility of a JMS
client and the enterprise features of a stateless session bean. The MDB does
not have a 'home' or 'component' interface. It instead implements the MessageDrivenBean
interface which inturn extends the javax.ejb.Enterprisebean interface. This
ensures that the MDB can be controlled by the ejb container just like any other
enterprise bean. The MDB also implements the javax.jms.MessageListener
interface which helps it to adhere to the JMS messaging API. As per the EJB2.0
spec MDB only supports JMS based messaging systems. But in the new EJB2.1
specification it is proposed to support other kinds of messaging systems. The
class definition is shown below.
public class MessageBean implements MessageDrivenBean,MessageListener
MBD Lifecycle
The Message driven bean has two states–-the 'does not exist' state
and the 'method-ready' state. Initially the bean
exists in the does not exist state. When the container starts up it may load a
few instances into memory so that they can be in the ready state to consume messages.
When a bean moves from the 'does not exist' state to the 'method-ready' state,
the container first invokes the Class.newInstance()
method to create a new instance of the bean. It then invokes the setMessageDrivenContext()
method to set the reference to the ejbContext. This provides a reference to the
MessageDrivenContext Interface which is in turn used to handle transaction and
security issues in the MDB. Finally the ejbCreate() method is invoked by the
container. Message driven beans have only one ejbCreate() method and they are
called only once in the lifetime of a Message driven bean.
When the bean is in the 'method-ready' state it
is ready to consume messages. The container allocates a bean to consume a
message when it arrives in the container. When a bean is servicing a message it
cannot service another message. Subsequent messages are delegated to other
instances existing in the pool. Once the bean is done servicing a message it is
again returned to the 'method-ready' and is ready to process a new message. If
the container cannot find a bean in the pool to service a message it
transitions another bean from the 'does not exist' state to the 'method-ready'
state.
Bean instances leave the
Method-Ready Pool for the Does Not Exist state when the server no longer needs
them. This occurs when the server decides to reduce the total size of the
Method-Ready Pool by removing one or more instances from memory. The process
begins by invoking the ejbRemove() method on the
instance. At this time, the bean instance should perform any cleanup
operations, such as closing open resources. The ejbRemove() method
is invoked only once in the life cycle of an MDB
instance--when it is about to transition to the Does Not Exist state. During
the ejbRemove() method, the MessageDrivenContext and access to the
JNDI ENC are still available to the bean
instance. Following the execution of the ejbRemove() method, the
bean is dereferenced and eventually garbage
collected.
Benoy Jose is a web developer with over six years of
experience in J2EE and Microsoft technologies. He is
a Sun Cetified programmer and enjoys writing technical
and non-technical articles for various magazines.
New on the Java Boutique:
New Review:
Time Management Made Easy with the Quartz Enterprise Job Scheduler
Why not just use the Java timer API? This open source scheduling
API boasts simplicity, ease-of-integration, a well-rounded feature
set, and it's free!
New Applet:
Reverse Complement
Reverse Complement is a simple applet that converts DNA or RNA
sequences into three useful formats.
Elsewhere on internet.com:
WebDeveloper Java
Lots of Java information on webdeveloper.com
WDVL Java
Thorough Java resource at the Web Developer's Virtual Library.
ScriptSearch Java
Hundreds of free Java code files to download.
jGuru: Your View of the Java Universe
Customizable portal with online training, FAQs, regular news updates, and tutorials.
|