Tutorials : Message Driven Beans :

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.

   

How to Add Java Applets to Your Site

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.