The Java EE 6 Tutorial

The Message-Driven Bean Class

The code for the SimpleMessageBean class illustrates the requirements of a message-driven bean class:

It is recommended, but not required, that a message-driven bean class implement the message listener interface for the message type it supports. A bean that supports the JMS API implements the javax.jms.MessageListener interface.

Unlike session beans and entities, message-driven beans do not have the remote or local interfaces that define client access. Client components do not locate message-driven beans and invoke methods on them. Although message-driven beans do not have business methods, they may contain helper methods that are invoked internally by the onMessage method.

For the GlassFish Server, the @MessageDriven annotation typically contains a mappedName element that specifies the JNDI name of the destination from which the bean will consume messages. For complex message-driven beans, there can also be an activationconfig element containing @ActivationConfigProperty annotations used by the bean.

A message-driven bean can also inject a MessageDrivenContext resource. Commonly you use this resource to call the setRollbackOnly method to handle exceptions for a bean that uses container-managed transactions.

Therefore, the first few lines of the SimpleMessageBean class look like this:

@MessageDriven(mappedName="jms/Queue", activationConfig =  {
        @ActivationConfigProperty(propertyName = "acknowledgeMode",
                                  propertyValue = "Auto-acknowledge"),
        @ActivationConfigProperty(propertyName = "destinationType",
                                  propertyValue = "javax.jms.Queue")
    })
public class SimpleMessageBean implements MessageListener {
    @Resource
    private MessageDrivenContext mdc;
    ...

NetBeans IDE typically creates a message-driven bean with a default set of @ActivationConfigProperty settings. You can delete those you do not need, or add others. Table 17–1 lists commonly used properties.

Table 17–1 @ActivationConfigProperty Settings for Message-Driven Beans

Property Name 

Description 

acknowledgeMode

Acknowledgment mode; see Controlling Message Acknowledgment for information

destinationType

Either javax.jms.Queue or javax.jms.Topic

subscriptionDurability

For durable subscribers, set to Durable; see Creating Durable Subscriptions for information

clientId

For durable subscribers, the client ID for the connection 

subscriptionName

For durable subscribers, the name of the subscription 

messageSelector

A string that filters messages; see JMS Message Selectors for information, and see An Application That Uses the JMS API with a Session Bean for an example

addressList

Remote system or systems to communicate with; see An Application Example That Consumes Messages from a Remote Server for an example

The onMessage Method

When the queue receives a message, the EJB container invokes the message listener method or methods. For a bean that uses JMS, this is the onMessage method of the MessageListener interface.

A message listener method must follow these rules:

The onMessage method is called by the bean’s container when a message has arrived for the bean to service. This method contains the business logic that handles the processing of the message. It is the message-driven bean’s responsibility to parse the message and perform the necessary business logic.

The onMessage method has a single argument: the incoming message.

The signature of the onMessage method must follow these rules:

In the SimpleMessageBean class, the onMessage method casts the incoming message to a TextMessage and displays the text:

public void onMessage(Message inMessage) {
    TextMessage msg = null;

    try {
        if (inMessage instanceof TextMessage) {
            msg = (TextMessage) inMessage;
            logger.info("MESSAGE BEAN: Message received: " +
                msg.getText());
        } else {
            logger.warning("Message of wrong type: " +
                inMessage.getClass().getName());
        }
    } catch (JMSException e) {
        e.printStackTrace();
        mdc.setRollbackOnly();
    } catch (Throwable te) {
        te.printStackTrace();
    }
}