Version 11

    Message Driven Beans

     

    Brief Over View on Message Driven Beans(MDB)

     

     

    Characteristics:

    • Executes upon receipt of a single client message.

    • Is asynchronously invoked.

    • Can be transaction-aware.

    • May update shared data in an underlying database.

    • Does not represent directly shared data in the database, although it may access and update such data.

    • Is relatively short-lived.

    • Is stateless.

    • Is removed when the EJB container crashes. The container has to re-establish a new message-driven object to continue computation.

     

    States of a MDB:

    There are mainly two different states of MDB, they are:

    • Does not Exist State.

    • Method-Ready Pool State.

     

    Life cycle of a MDB:

    • A message-driven bean instance's life starts when the container invokes newInstance on the message-driven bean class to create a new instance. Next, the container calls setMessageDrivenContext followed by ejbCreate on the instance.

    • The message-driven bean instance is now ready to be delivered a message sent to its associated destination or endpoint by any client or a call from the container to the ejbTimeout method.

    • When the container no longer needs the instance (which usually happens when the container wants to reduce the number of instances in the method-ready pool), the container invokes ejbRemove on it. This ends the life of the message-driven bean instance.

     

    Client View of MDB:

    A message-driven bean is simply a message consumer. The client sends messages to the destination or endpoint for which the message-driven bean is the message listener just as it would to any other destination or endpoint. The message-driven bean, as a message consumer, handles the processing of the messages.

     

    From the perspective of the client, the existence of a message-driven bean is completely hidden behind the destination or endpoint for which the message-driven bean is the message listener.

     

    MDB Interfaces:

    MessageDrivenBean Interface ~ All message-driven beans must implement the MessageDrivenBean interface.

    The setMessageDrivenContext method is called by the bean's container to associate a message-driven bean instance with its context maintained by the container. Typically a message-driven bean instance retains its message-driven context as part of its state.

     

    The ejbRemove notification signals that the instance is in the process of being removed by the container. In the ejbRemove method, the instance releases the resources that it is holding.

     

    Message Listener Interface ~

    Message-driven bean class must implement the appropriate message listener interface for the messaging type that the message-driven bean supports. The specific message listener interface that is implemented by a message-driven bean class distinguishes the messaging type that the message-driven bean

    supports.

     

    NOTE : The message-driven bean class's implementation of the javax.jms.MessageListener interface distinguishes the message-driven bean as a JMS message-driven bean.

     

    Message-DrivenContext Interface:

    Container provides the message-driven bean instance with a MessageDrivenContext. This gives the message-driven bean instance access to the instance's context maintained by the container. The MessageDrivenContext interface has the following methods:

     

    • The setRollbackOnly method allows the instance to mark the current transaction such that the only outcome of the transaction is a rollback. Only instances of a message-driven bean with container-managed transaction demarcation can use this method.

    • The getRollbackOnly method allows the instance to test if the current transaction has been marked for rollback. Only instances of a message-driven bean with container-managed transaction demarcation can use this method.

    • The getUserTransaction method returns the javax.transaction.UserTransaction interface that the instance can use to demarcate transactions, and to obtain transaction status. Only instances of a message-driven bean with bean-managed transaction demarcation can use this method.

    • The getTimerService method returns the javax.ejb.TimerService interface.

    • The getCallerPrincipal method returns the java.security.Principal that is associated with the invocation.

    • The isCallerInRole method is inherited from the EJBContext interface. Message-driven bean instances must not call this method.

    • The getEJBHome and getEJBLocalHome methods are inherited from the EJBContext interface. Message-driven bean instances must not call these methods.

     

    Message Processing:

    Container allows many instances of a message-driven bean class to be executing concurrently, thus allowing for the concurrent processing of a stream of messages. No guarantees are made as to the exact order in which messages are delivered to the instances of the message-driven bean class, although the

    container should attempt to deliver messages in order when it does not impair the concurrency of message processing. Message-driven beans should therefore be prepared to handle messages that are out of sequence: for example, the message to cancel a reservation may be delivered before the message to make the reservation.

     

    Message-Driven Bean Methods Transaction Context:

    Bean's message listener method is invoked in the scope of a transaction determined by the transaction attribute specified in the deployment descriptor. If the bean is specified as using container-managed transaction demarcation, either the Required or the NotSupported transaction attribute must be used.

     

    When a message-driven bean using bean-managed transaction demarcation uses the javax.transaction.UserTransaction interface to demarcate transactions, the message receipt that causes the bean to be invoked is not part of the transaction. If the message receipt is to be part of the transaction,

    container-managed transaction demarcation with the Required transaction attribute must be used.

     

    A message-driven bean's newInstance, setMessageDrivenContext, ejbCreate, and

    ejbRemove methods are called with an unspecified transaction context.

     

    Exception Handling in MDB:

    A message-driven bean's message listener method must not throw the java.rmi.RemoteException. Message-driven beans should not, in general, throw RuntimeExceptions.

     

    A RuntimeException thrown from any method of the message-driven bean class (including a message listener method and the callbacks invoked by the container) results in the transition to the 'does not exist' state. If a message-driven bean uses bean-managed transaction demarcation and throws a RuntimeException, the container should not acknowledge the message.

     

    From the client perspective, the message consumer continues to exist. If the client continues sending messages to the destination or endpoint associated with the bean, the container can delegate the client's messages to another instance.

     

    The message listener methods of some messaging types may throw application exceptions. An application exception is propagated by the container to the resource adapter.

     

    JMX Notifications (4.0.2+)

    The following JMX notifications were added to the 4.0.2 release. The notifications are emitted by the JMSContainerInvoker associated with the MDB, so this is the source of the notifications. The format of the JMSContainerInvoker MBean name is "jboss.j2ee:service=EJB,plugin=invoker,binding={invoker-proxy-binding/name},jndiName={local-jndi-name}"

    where {invoker-proxy-binding/name} = the container invoker-proxy-binding/invoker-proxy-binding/name value, and the local-jndi-name is the jboss.xml local-jndi-name value. An example name is:

    "jboss.j2ee:service=EJB,plugin=invoker,binding=message-driven-bean,jndiName=local/StrictlyPooledMDB@33020593

     

    NOTE: that the default MDB local-jndi-name is derived from the ejb-name with a random integer appended, so to have a usable MBean name requires an explicit local-jndi-name setting in the jboss.xml descriptor.

     

    The JMX notification types include:

    • org.jboss.ejb.plugins.jms.CONNECTING (before it tries to connect)

    • org.jboss.ejb.plugins.jms.CONNECTED (after it has connected)

    • org.jboss.ejb.plugins.jms.DISCONNECTING (when it tries to disconnect)

    • org.jboss.ejb.plugins.jms.FAILURE (when the exception handler is invoked)

    • org.jboss.ejb.plugins.jms.DISCONNECTED (after it has disconnected)

     

    MDB's ejbRemove call:

    The Bean Provider cannot assume that the container will always invoke the ejbRemove method on a

    message-driven bean instance. The following scenarios result in ejbRemove not being called on an

    instance:

    • A crash of the EJB container.

    • A system exception thrown from the instance's method to the container.

     

    If the message-driven bean instance allocates resources in the ejbCreate method and/or in the message listener method, and releases normally the resources in the ejbRemove method, these resources will not be automatically released in the above scenarios. The application using the message-driven bean should provide some clean up mechanism to periodically clean up the unreleased resources.

     

    Sample Message Driven Bean

    This sample is create using,

    • JBoss 3.2.5

    • JBoss-IDE 1.2.430

    • Eclipse 3.0.0

    Source code is attached. Client code can be found at QueueExample.

     

    Referenced by: