The MDB class must implement the javax.jms.MessageListener and the javax.ejb.MessageDrivenBean interfaces. In addition to the onMessage method, the following must be implemented:
A public constructor with no argument.
public void ejbCreate(): with no arguments, called at the bean-instantiation time. It may be used to allocate some resources, such as connection factories, for example if the bean sends messages, or datasources or if the bean accesses databases.
public void ejbRemove(): usually used to free the resources allocated in the ejbCreate method.
public void setMessageDrivenContext(MessageDrivenContext mdc): called by the container after the instance creation, with no transaction context. The JOnAS container provides the bean with a container context that can be used for transaction management, for example, for calling setRollbackOnly(), getRollbackOnly(), getUserTransaction().
The following is an example of an MDB class:
public class MdbBean implements MessageDrivenBean, MessageListener { private transient MessageDrivenContext mdbContext; public MdbBean() {} public void setMessageDrivenContext(MessageDrivenContext ctx) { mdbContext = ctx; } public void ejbRemove() {} public void ejbCreate() {} public void onMessage(Message message) { try { TextMessage mess = (TextMessage)message; System.out.println( "Message received: "+mess.getText()); }catch(JMSException ex){ System.err.println("Exception caught: "+ex); } } } |
The destination associated with an MDB is specified in the deployment descriptor of the bean. A destination is a JMS-administered object, accessible via JNDI (the Java Naming and Directory Interface). The description of an MDB in the EJB 2.1 deployment descriptor contains the following elements, which are specific to MDBs:
The JMS acknowledgement mode: auto-acknowledge or dups-ok-acknowledge (refer to the JMS specification for the definition of these modes)
An eventual JMS message selector: this is a JMS concept which allows the filtering of the messages sent to the destination
A message-driven-destination, which contains the destination type (Queue or Topic) and the subscription durability (in the case of Topic)
The following example illustrates such a deployment descriptor:
<enterprise-beans> <message-driven> <description>Describe here the message driven bean Mdb</description> <display-name>Message Driven Bean Mdb</display-name> <ejb-name>Mdb</ejb-name> <ejb-class>samplemdb.MdbBean</ejb-class> <transaction-type>Container</transaction-type> <message-selector>Weight >= 60.00 AND LName LIKE 'Sm_th'</message-selector> <message-driven-destination> <destination-type>javax.jms.Topic</destination-type> <subscription-durability>NonDurable</subscription-durability> </message-driven-destination> <acknowledge-mode>Auto-acknowledge</acknowledge-mode> </message-driven> </enterprise-beans> |
If the transaction type is "container," the transactional behavior of the MDB's methods are defined as for other enterprise beans in the deployment descriptor, as in the following example:
<assembly-descriptor> <container-transaction> <method> <ejb-name>Mdb</ejb-name> <method-name>*</method-name> </method> <trans-attribute>Required</trans-attribute> </container-transaction> </assembly-descriptor> |
For the onMessage method, only the Required or NotSupported transaction attributes must be used, since there can be no pre-existing transaction context.
For the message selector specified in the previous example, the sent JMS messages are expected to have two properties, "Weight" and "LName." For example, to assign the JMS client program sending the messages:
message.setDoubleProperty("Weight",75.5); message.setStringProperty("LName","Smith"); |
Such a message will be received by the Message-Driven Bean. The message selector syntax is based on a subset of the SQL92. Only messages whose headers and properties match the selector are delivered. Refer to the JMS specification for more details.
The JNDI name of a destination associated with an MDB is defined in the JOnAS-specific deployment descriptor, within a jonas-message-driven element, as illustrated in the following:
<jonas-message-driven> <ejb-name>Mdb</ejb-name> <jonas-message-driven-destination> <jndi-name>sampleTopic</jndi-name> </jonas-message-driven-destination> </jonas-message-driven> |
Once the destination is established, a client application can send messages to the MDB through a destination object obtained via JNDI as follows:
Queue q = context.lookup("sampleTopic"); |
If the client sending messages to the MDB is an EJB component itself, it is preferable that it use a resource environment reference to obtain the destination object. The use of resource environment references is described in Section 26.2 Writing JMS Operations Within an Application Component.