Developing an enterprise application to use message-driven beans

Applications can use message-driven beans as asynchronous message consumers. You deploy a message-driven bean as a message listener for a destination. The message-driven bean is invoked by an activation specification or a JMS listener when a message arrives on the input destination that is being monitored.

About this task

You develop an enterprise application to use a message-driven bean as with any other enterprise bean, except that a message-driven bean does not have a home interface or a remote interface.

You should develop your message-driven bean to delegate the business processing of incoming messages to another enterprise bean, which provides clear separation of message handling and business processing. This separation also means that the business processing can be invoked either by the arrival of incoming messages or, for example, by a WebSphere® J2EE client. Responses can be handled by another enterprise bean acting as a sender bean, or they can be handled in the message-driven bean.

EJB 2.0 message-driven beans support only Java™ Message Service (JMS) messaging. EJB 2.1 and EJB 3 message-driven beans can support other messaging types in addition to JMS. All message-driven beans must implement the MessageDrivenBean interface. For JMS messaging, a message-driven bean must also implement the message listener interface javax.jms.MessageListener. Other Java EE Connector Architecture (JCA)-compliant resource adapters might provide their own message listener interfaces that must be implemented.

You can use the New Enterprise Bean wizard of Rational® Application Developer to create an enterprise bean with a bean type of Message-driven bean. The wizard creates appropriate methods for the type of bean.

By convention, the message-driven bean class is named nameBean, where name is the name you assign to the message-driven bean; for example:
public class MyJMSppMDBBean implements MessageDrivenBean, javax.jms.MessageListener

A message-driven bean can be registered with the EJB timer service for time-based event notifications if it also implements the javax.ejb.TimedObject interface, and invokes the timer callback method by the following call: void ejbTimeout(Timer). At the scheduled time, the container then calls the message-driven bean ejbTimeout method.

The message-driven bean class must define and implement the following methods:
  • onMessage(message), which must meet the following requirements:
    • The method must have a single argument of type javax.jms.Message.
    • The throws clause must not define any application exceptions.
    • If the message-driven bean is configured to use bean-managed transactions, it must call the javax.transaction.UserTransaction interface to scope the transactions. Because these calls occur inside the onMessage() method, the transaction scope does not include the initial message receipt. For more information, see the topic about message-driven beans transaction support.

    To handle the message within the onMessage() method (for example, to pass the message on to another enterprise bean), you use standard JMS. This is known as bean-managed messaging.

    If you are using a JCA-compliant resource adapter with a different message listener interface, another method besides the onMessage() method might be needed. For information about the message listener interface needed, see the documentation that was provided with your JCA-compliant resource adapter.

  • ejbCreate()

    You must define and implement an ejbCreate method for each way in which you want a new instance of an enterprise bean to be created.

  • ejbRemove()

    This method is invoked by the container when a client invokes the remove method inherited by the enterprise bean home interface from the javax.ejb.EJBHome interface. This method must contain any code that you want to execute before an enterprise bean instance is removed from the container (and the associated data is removed from the data source).

  • ejbTimeout(Timer)

    This method is needed only to support notifications from the timer service, and contains the business logic that handles time events received.

Procedure

  1. Create the Enterprise Application project.
  2. Create the message-driven bean class.
    You can use the New Enterprise Bean wizard of Rational(r) Application Developer to create the enterprise bean with a bean type of Message-driven bean.

    For an example of how to create the message-driven bean class, see the Example section of this topic. For more information, see Creating message-driven beans in the Rational Application Developer documentation.

    The result of this step is a message-driven bean that can be assembled into an EAR file for deployment.
  3. Optional: Use the EJB deployment descriptor editor to review and, if needed, change the deployment attributes.
    You can use the EJB deployment descriptor editor to review deployment attributes that you specified on the EJB creation wizard (such as Transaction type and Message selector) and other default deployment attributes.

    If needed, you can override the values of these attributes later, after the enterprise application has been exported into an EAR file for deployment, as described in Configuring deployment attributes for a message-driven bean against JCA 1.5-compliant resources and Configuring deployment attributes for a message-driven bean against a listener port.

    1. In the property pane, select the Bean tab.
    2. On the main panel, configure the Transaction type attribute.
      Transaction type
      This attribute determines whether the message-driven bean manages its own transactions, or whether the container manages transactions on behalf of the bean.
      Bean
      The message-driven bean manages its own transactions.
      Container
      The container manages transactions on behalf of the bean.
    3. Under Activation Configuration, review the following attributes:
      acknowledgeMode
      This attribute determines how the session acknowledges any messages it receives.
      Auto Acknowledge
      The session automatically acknowledges delivery of each message.
      Dups OK Acknowledge
      The session lazily acknowledges the delivery of messages. This setting is likely to result in the delivery of some duplicate messages if JMS fails, so it should be used only by consumer applications that are tolerant of duplicate messages.

      As defined in the EJB specification, clients cannot use the Message.acknowledge() method to acknowledge messages. If a value of CLIENT_ACKNOWLEDGE is passed on the createxxxSession call, then messages are automatically acknowledged by the application server and the Message.acknowledge() method is not used.

      Note:

      The acknowledgment is sent when the message is deleted.

      If you have a non-transactional message-driven bean, the system either deletes the message when the message-driven bean starts, or when the message-driven bean completes. If the message-driven bean generates an exception, and therefore does not complete, the system takes one of the following actions:
      • If the system is configured to delete the message when the message-driven bean completes, then the message is dispatched to a new instance of the message-driven bean, so the message has another opportunity to be processed.
      • If the system is configured to delete the message when the message-driven bean starts, then the message is lost.

      The message is deleted when the message-driven bean starts if the quality of service is set to Best effort nonpersistent. For all other qualities of service, the message is deleted when the message-driven bean completes.

      destinationType
      This attribute determines whether the message-driven bean uses a queue or topic destination.
      Queue
      The message-driven bean uses a queue destination.
      Topic
      The message-driven bean uses a topic destination.
      subscriptionDurability
      This attribute determines whether a JMS topic subscription is durable or nondurable.
      Durable
      A subscriber registers a durable subscription with a unique identity that is retained by JMS. Subsequent subscriber objects with the same identity resume the subscription in the state it was in for the earlier subscriber. If there is no active subscriber for a durable subscription, JMS retains the subscription messages until they are received by the subscription or until they expire.
      Nondurable
      Nondurable subscriptions last for the lifetime of their subscriber object. This means that a client sees the messages published on a topic only while its subscriber is active. If the subscriber is not active, the client is missing messages published on its topic.

      A nondurable subscriber can only be used in the same transactional context (for example, a global transaction or an unspecified transaction context) that existed when the subscriber was created.

      messageSelector
      This attribute determines the JMS message selector that is used to select which messages the message-driven bean receives. For example:
      JMSType='car' AND color='blue' AND weight>2500

      The selector string can refer to fields in the JMS message header and fields in the message properties. Message selectors cannot reference message body values.

    4. Specify bindings deployment attributes.

      Under WebSphere Bindings, select the JCA Adapter option then specify the bindings deployment attributes:

      ActivationSpec JNDI name
      This attribute specifies the JNDI name of the activation specification that is used to deploy this message-driven bean. This name must match the name of an activation specification that you define to WebSphere Application Server.
      ActivationSpec Authorization Alias
      This attribute specifies the name of an authentication alias used for authentication of connections to the JCA resource adapter. An authentication alias specifies the user ID and password that is used to authenticate the creation of a new connection to the JCA resource adapter.
      Destination JNDI name
      This attribute specifies the JNDI name that the message-driven bean uses to look up the JMS destination in the JNDI namespace.
    5. Optional: Specify Destination Link to enable message linking.

      Message linking allows the routing of messages to a specific message-driven bean in a deployment. Message linking allows message flow to be orchestrated between components in the same application.

      For a message to be consumed and processed by a message-driven bean, the<message-destination-link> element must be defined in the deployment descriptor associated with the message-driven bean. The destination identified by the <message-destination-link> element corresponds to the logical destination.

      When the <message-destination-ref> includes a <message-destination-link> element, messages are consumed at that destination.

      In order to get the message-driven bean to consume messages sent to a destination, you can declare a <message-destination-link> element in the deployment descriptor, or alternatively set it in the activation specification.

  4. Assemble and package the application for deployment.

Results

The result of this task is an EAR file, containing the message-driven bean, for the enterprise application that can be deployed in WebSphere Application Server.

Example

The following example shows how to create the message-driven bean class. The example code shows how to access the text and the JMS MessageID, from a JMS message of type TextMessage. In this example, first the onMessage() method of a message-driven bean is used to unpack the incoming text message and to extract the text and message identifier; then a private putMessage method (defined within the same message bean class) is used to put the message onto another queue:


public void onMessage(javax.jms.Message msg)
{
        String text      = null;
        String messageID = null;

        try
        {
                text = ((TextMessage)msg).getText();

                System.out.println("senderBean.onMessage(), msg text2: "+text);

                //
                // store the message id to use as the Correlator value
                //
                messageID = msg.getJMSMessageID();

                // Call a private method to put the message onto another queue
                putMessage(messageID, text);
        }
        catch  (Exception err)
        {
                err.printStackTrace();
        }
        return;
}

What to do next

After you have developed an enterprise application to use message-driven beans, configure and deploy the application. For example, define activation specifications for the message-driven beans and, optionally, change the deployment descriptor attributes for the application. For more information, see Deploying an enterprise application to use message-driven beans with JCA 1.5-compliant resources and Deploying an enterprise application to use message-driven beans with listener ports.