Wednesday 4 November 2009

JMS: Message-driven Bean - Part 3

Introduction
The message-driven bean model develops an Enterprise Bean that is asynchro­nously invoked by the container to handle the processing of incoming 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.



Implementing the MessageListener
A message-driven bean implements javax.jms.MessageListener interface (JMS Message driven bean). The container uses the listener interface to register the message-driven bean with the message provider and to pass incoming messages by invoking implemented message listener methods. There are different ways to define a message-driven bean.
1.     @MessageDriven (name="ShippingRequestJMSProcessor",
              messageListenerInterface="javax.jms.MessageListener")
public class ShippingRequestProcessorMDB {

2.     public class ShippingRequestProcessorMDB implements MessageListener
3.     Deployment descriptor.

The bean’s message listener method void onMessage(Message message) is called by the container when a message has arrived for the bean to service. The message lis­tener method contains the business logic that handles the processing of the message.
Note: If the message-driven bean class implements more than one interface other than java.io.Serial­izable, java.io.Externalizable, or any of the interfaces defined by the javax.ejb pack­age, the message listener interface must be specified by the messageListenerInterface element of the MessageDriven annotation or the messaging-type element of the mes­sage-driven deployment descriptor element.
Activation Configuration Properties
The activationConfig property of the @MessageDriven annotation allows you to provide messaging system-specific configuration information through an array of ActivationConfigProperty instances.
ActivationConfigProperty
propertyName
propertyValue
Description
destinationType
javax.jms.Queue
Tells the container this JMS MDB is listening to a queue.
javax.jms.Topic
Tells the container this JMS MDB is listening to a topic.
destinationName
jms/ShippingRequestQueue
Specifies that we are listening for messages arriving at a destination with the JNDI name of jms/ShippingRequestQueue.
connectionfactoryJndiName
jms/QueueConnectionFactory
Specifies the JNDI name of the connection factory that should be used to create JMS connections for the MDB.
acknowledgeMode
AUTO_KNOWLEDGE
The session automatically acknowledges receipt after a message has been received or is successfully processed.
DUPS_OK_ACKNOWLEDGE
The session can lazily acknowledge receipt of the message.
subscriptionDurability
Durable
Once a consumer obtains a durable subscription on a topic, all messages sent to the topic are guaranteed to be delivered to the consumer.
NonDurable (By default)
In the pub-sub domain, a message is distributed to all currently subscribed consumers. In general, this is much like a broadcast message in that anyone who is not connected to the topic at the time does not receive a copy the message.
messageSelector
JMSType = ‘car’ AND color = ‘blue’ and weight > 2500
Determines which messages a JMS message-driven bean is to receive.

Example 1.
@MessageDriven(
           name="ShippingRequestProcessor",
           activationConfig = {
               @ActivationConfigProperty(
                   propertyName="destinationType",
                   propertyValue="javax.jms.Queue"),
               @ActivationConfigProperty(
                   propertyName="connectionFactoryJndiName",
                   propertyValue="jms/QueueConnectionFactory"
               ),
               @ActivationConfigProperty(
                   propertyName="destinationName",
                   propertyValue="jms/ShippingRequestQueue")
           }
       )
Using bean lifecycle callbacks
The container is responsible for the following:
1.     A MDB instance’s life starts when the container invokes newInstance on the MDB class to create a new instance. Next, the container injects the bean’s MessageDriverContext, if applicable, and performs any other dependency injection as specified by metadata annotations on the bean class or by the deployment descriptor. The container then calls the bean’s PostConstruct lifecycle callback methods, if any.
2.     The MDB 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 timeout callback method.
3.     When the container no longer needs the instance (happens when the container wants to reduce the number of instances in the method-ready pool), the container invokes the PreDestroy lifecycle callback methods for it, if any. This ends the life of the MDB instance.





The following lifecycle event callbacks are supported for message-driven beans.
PostConstruct.
PreDestroy.
A message driven bean can be registered with the EJB timer service for time-based event notifications. The container invokes the appropriate bean instance timeout callback method when a timer for the bean has expired.
The AroundInvoke business method interceptor methods are supported for message-driven beans.
Serializing Message-Driven Bean Methods
The container serializes calls to each message-driven bean instance. Most containers will support many instances of a message-driven bean executing concurrently; however, each instance sees only a serial­ized sequence of method calls. Therefore, a message-driven bean does not have to be coded as reentrant.
The container must serialize all the container-invoked callbacks (e.g., lifecycle callback interceptor methods and timeout callback methods), and it must serialize these callbacks with the message listener method calls.
Concurrency of Message Processing
A 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 mes­sage 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.
Transaction Context of Message-Driven Bean Methods and acknowledgment
If the MDB uses container-managed transaction demarcation:
§          In message listener methods
REQUIRED. The message receipt is part of the transac­tion and message acknowledgment is handled automatically as a part of the transaction commit.
NOT_SUPPORTED.
§          In timeout callback methods
REQUIRED.
REQUIRES_NEW.
NOT_SUPPORTED.
If the MDB uses bean-managed transaction demarcation uses the javax.trans­action.UserTransaction interface to demarcate transactions, the message receipt is not part of the transaction. The receipt is acknowledged by the container (AUTO_ACKNOWLEDGE semantics or DUPS_OK_ACKNOWLEDGE).
Dealing with Exceptions
A message-driven bean’s message listener method must not throw the java.rmi.RemoteExcep­tion.
Message-driven beans should not, in general, throw RuntimeExceptions.
A RuntimeException that is not an application exception thrown from any method of the mes­sage-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 trans­action 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 applica­tion exception is propagated by the container to the resource adapter.

Some Basic Scenarios
 Scenario 1.

 Scenario 2.





1 comment: