An Introduction to the Enterprise JavaBeans 3.0 (EJB 3) Specification

Message-driven Beans

Let's now look at the final type of EJB: message-driven beans.

Business interface

The business interface of a message-driven bean (MDB) is the message-listener interface that is determined by the messaging type in use for the bean. The interface is javax.jms.MessageListener. The message-driven bean must implement the appropriate message listener interface for the messaging type that the message-driven bean supports or must designate its message-listener interface using the @MessageDriven annotation or the deployment descriptor.

Bean class

In EJB 3.0, the MDB bean class is annotated with the @MessageDriven annotation, which specifies the message queue this MDB monitors (such as queue/mdb).

The bean class needs to implement the MessageListener interface, which defines only one method, onMessage(). When a message arrives in the queue monitored by this MDB, the container calls the bean class's onMessage() method and passes the incoming message in as the call parameter.

In our example, the TraderBean.onMessage() method retrieves the message body, parses out the parameters, performs the trade, and saves the result to a static data manager class. The "sent" timestamp on the service request message serves as the unique ID for the calculation record (it works well for low-volume Web sites). A check.jsp JSP page picks up and displays the calculation record based on the message ID:



    @MessageDriven(activateConfig =
    {
      @ActivationConfigProperty(propertyName="destinationType",
        propertyValue="javax.jms.Queue"),
      @ActivationConfigProperty(propertyName="destination",
        propertyValue="queue/mdb")
    })
    public class TraderBean implements MessageListener {
    
      public void onMessage (Message msg) {
        try {
          TextMessage tmsg = (TextMessage) msg;
          Timestamp sent =
              new Timestamp(tmsg.getLongProperty("sent"));
          StringTokenizer st =
              new StringTokenizer(tmsg.getText(), ",");
    
               buy ("SNPS",1000);
    
          RecordManager.addRecord (sent, "BUY SUCCESSFUL");
    
        } catch (Exception e) {
          e.printStackTrace ();
        }
      }
      // ... ...
    }
    

Sending a message

To use the message-driven bean, the client (such as the JSP page, trader.jsp, in this case) uses the standard JMS API to obtain the target message queue to the MDB by way of the queue name (queue/mdb), and then it sends the message to the queue:



    try {
      InitialContext ctx = new InitialContext();
      queue = (Queue) ctx.lookup("queue/mdb");
      QueueConnectionFactory factory =
        (QueueConnectionFactory) ctx.lookup("ConnectionFactory");
      cnn = factory.createQueueConnection();
      sess = cnn.createQueueSession(
               false,QueueSession.AUTO_ACKNOWLEDGE);
    } catch (Exception e) {
        e.printStackTrace ();
    }
    TextMessage msg = sess.createTextMessage("SNPS",1000);
    sender = sess.createSender(queue);
    sender.send(msg);
    

Callbacks for message-driven beans

The following life cycle event callbacks are supported for message-driven beans:

  • PostConstruct
  • PreDestroy

What Happens to the Old Entity Model?

The old entity model is still going to remain a part of EJB, and it always will be a part of EJB, for compatibility reasons. The Expert Group is currently looking at a number of the new features in EJB 3.0, which would potentially be useful for people using the old programming model, and thinking about making those available for people using the older programming model. EJB 3.0 plans to extend the EJB-QL for the EJB 2.1-style CMP entity beans. So if you want to stick to the old programming model for a while, you will be able to do that and still use some of the new functionality.

Conclusion

EJB 3.0 goes a long way toward making the EJB programming experience a pleasant one by simplifying development, facilitating test-driven development, and focusing more on plain Java objects (POJOs) rather than on complex APIs. One of the important aspects that we have not covered in detail in this article is the new persistence framework defined in the specification. For details, check the EJB 3.0 API specification, and download the EJB 3.0 persistence documentation.

BEA Systems is working actively on its EJB3 implementation strategy in BEA WebLogic Server. Details on the implementation and the timeline will be provided on this Web site when they are finalized.

Additional Reading

Vimala Ranganathan is a QA engineer on the workshop team. She has over eight years of experience in Java SE/Java EE technologies.

Anurag Pareek is an Escalation Engineer working for BEA Systems. He has extensive experience in implementing, tuning and troubleshooting mission-critical, high-availability applications.