JMS - Message Driven Bean


A Message Driven Bean or MDB is a JMS message consumer that usually implements some message processing and/or routing logic. The bean registers interest (via deployment descriptor) in a Queue or Topic of its choice, implements MessageListener and MessageDrivenBean interface, and awaits arrival of asynchronous messages.

Does an MDB have a home or a component interface?
Messages are delivered asynchronously to a bean by the messaging service provider (e.g. IBM MQ) or an application server (e.g. JbossMQ). The bean cannot be invoked by a client and hence does not require a home or a component interface.An MDB does not have any client-visible identity or a conversational state - all the instances of the bean are treated equivalent for servicing receipt of a message. Typically, a server creates a pool of MDB instances and keep them in method-ready state. On arrival of a message, one of the instances is assigned to the client. After the onMessage() method execution, the bean is returned to the pool of available beans. The J2EE (now JEE) container essentially controls the lifecycle of such a bean. The component pooling of MDB results in more scalable applications.

What are the required interfaces for an MDB?
A Message Driven Bean must implement the javax.ejb.MessageDrivenBen and javax.jms.MessageListener interfaces.The MessageDrivenBean interface looks like this:

1
2
3
4
5
6
7
8
package javax.ejb;  
 
public interface MessageDrivenBean extends EnterpriseBean {
	public void ejbRemove() throws EJBException;
	public void setMessageDrivenContext(MessageDrivenContext ctx)
			throws EJBException;  
 
}

setMessageDrivenContext() method receives the context as an argument and is called by the container during the bean object creation time. The container calls the ejbRemove() method at the time of destroying the bean instance, giving the bean a chance to free any previously allocated resources (in ejbCreate() mostly).

The MessageListener interface defines just a single method:

1
2
3
4
5
package javax.jms;  
 
public interface MessageListener {
	public void onMessage(Message message);
}

onMessage() method is invoked whenever a message is delivered to the client implementing this interface. The Message object is passed in as a parameter and the implementing class can then process this message.

The method should not throw an application or a javax.rmi.RemoteException. In general, an MDB should not throw any exception, although it may legally do so if desired. From the client view the message consumer continues to exist even if the bean does throw an application exception. In such a case, the container may assign another bean instance to the client.

What is MessageDrivenContext?
The MessageDrivenContext class extends EJBContext and contains several useful methods for transaction management. getUserTransaction() method returns the javax.transaction. UserTransaction object having the following methods:

begin() commit() rollback() getStatus() setRollbackOnly() setTransactionTimeout()

There are several other methods inherited from the EJBContext interface and may be irrelevant for a message-driven bean. For example, the methods getEJBHome() and getCallerPrincipal() should not be used with an MDB.

What transaction attributes are applicable for MDBs with declarative transaction?
Message-driven beans only support Required and NotSupported attributes. They do NOT support RequiresNew or Supports as they are never invoked within the context of a pre-existing transaction. They also do NOT support Mandatory and Never, as message-driven beans are only ever invoked by the container and as such would not make sense to support client-side transactions.

In case of bean managed, non-declarative transaction, the bean must close the UserTransaction by calling its commit() or rollback() before the onMessage() method returns.

0 Response to “JMS - Message Driven Bean”


Leave a Reply