BEA Logo BEA WebLogic Server Release 6.1

  Corporate Info  |  News  |  Solutions  |  Products  |  Partners  |  Services  |  Events  |  Download  |  How To Buy

   Programming WebLogic Enterprise JavaBeans:   Previous topic   |   Next topic   |   Contents   

 

Using Message-Driven Beans

 

The following sections describe how to develop and deploy message-driven beans in the EJB 2.0 for BEA WebLogic Server container. Because message-driven beans utilize parts of the standard JMS API, you should first become familiar with the WebLogic JMS messaging system before attempting to implement message-driven beans. See the Programming WebLogic JMS document for more information.

What Are Message-Driven Beans?

A message-driven bean is a special kind of EJB that acts as a message consumer in the WebLogic JMS messaging system. As with standard JMS message consumers, message-driven beans receive messages from a JMS Queue or Topic, and perform business logic based on the message contents.

EJB deployers create listeners to a Queue or Topic at deployment time, and WebLogic Server automatically creates and removes message-driven bean instances as needed to process incoming messages.

Differences Between Message-Driven Beans and Standard JMS Consumers

Because message-driven beans are implemented as EJBs, they benefit from several key services that are not available to standard JMS consumers. Most importantly, message-driven bean instances are wholly managed by the WebLogic Server EJB container. Using a single message-driven bean class, WebLogic Server creates multiple EJB instances as necessary to process large volumes of messages concurrently. This stands in contrast to a standard JMS messaging system, where the developer must create a MessageListener class that utilizes a server-wide session pool.

The WebLogic Server container provides other standard EJB services to message- driven beans, such as security services and automatic transaction management. These services are described in more detail in Transaction Management and in Transaction Services for Message-Driven Beans.

Finally, message-driven beans benefit from the write-once, deploy-anywhere quality of EJBs. Whereas a JMS MessageListener is tied to specific session pools, Queues, or Topics, message-driven beans can be developed independently of available server resources. A message-driven bean's Queues and Topics are assigned only at deployment time, utilizing resources available on the particular WebLogic Server instance.

Note: One limitation of message-driven beans compared to standard JMS listeners is that a given message bean deployment can be associated with only one Queue or Topic, as described in Deploying Message-Driven Beans in WebLogic Server. If your application requires a single JMS consumer to service messages from multiple Queues or Topics, you must use a standard JMS consumer, or deploy multiple message-driven bean classes.

Differences Between Message-Driven Beans and Stateless Session EJBs

In several ways, the dynamic creation and allocation of message-driven bean instances mimics the behavior of stateless session EJB instances. However, message-driven beans are different from stateless session EJBs (and other types of EJBs) in several significant ways:

Concurrent Support for Message-Driven Beans

Message-Driven Beans support concurrent processing for both topics and queues. Previously, only concurrent processing for Queues was supported.

To ensure concurrency, change the weblogic-ejb-jar.xml deployment descriptor max-beans-in-free-pool setting to >1. If this element is set to more than one, the container will spawn as many threads as specified. For more information on this element see, max-beans-in-free-pool.

Invoking a Message-Driven Bean

When a JMS Queue or Topic receives a message, use WebLogic Server to call an associated message-driven bean as follows:

  1. Obtain a new bean instance.

    Obtain a new bean instance from the connection pool if one already exists, or create a new one. See Creating and Removing Bean Instances.

  2. If the bean cannot be located in the pool and a new one must be created, call the bean's setMessageDrivenContext() to associate the instance with a container context. The bean can utilize elements of this context as described in Using the Message-Driven Bean Context.

  3. Call the bean's onMessage() method to perform business logic. See Implementing Business Logic with onMessage().

    Note: These instances can be pooled.

Developing Message-Driven Beans

To create message-driven EJBs, you must follow certain conventions described in the JavaSoft EJB 2.0 specification, as well as observe several general practices that result in proper bean behavior.

Bean Class Requirements

The EJB 2.0 specification provides detailed guidelines for defining the methods in a message-driven bean class. The following output shows the basic components of a message-driven bean class. Classes, methods, and method declarations in bold are required as part of the EJB 2.0 specification:

public class MessageTraderBean implements javax.ejb.MessageDrivenBean {

  public MessageTraderBean() {...}; 

    // An EJB constructor is required, and it must not 

    // accept parameters. The constructor must not be declared as

    // final or abstract.

  public void onMessage(javax.jms.Message MessageName) {...} 

    // onMessage() is required, and must take a single parameter of 

    // type javax.jms.Message. The throws clause (if used) must not 

    // include an application exception. onMessage() must not be

    // declared as final or static.

  public void ejbRemove() {...} 

    // ejbRemove() is required and must not accept parameters. 

    // The throws clause (if used) must not include an application 

    //exception. ejbRemove() must not be declared as final or static.

  finalize{}; 

  // The EJB class cannot define a finalize() method

}

Creating and Removing Bean Instances

The WebLogic Server container calls the message-driven bean's ejbCreate() and ejbRemove() methods when creating or removing an instance of the bean class. As with other EJB types, the ejbCreate() method in the bean class should prepare any resources that are required for the bean's operation. The ejbRemove() method should release those resources, so that they are freed before WebLogic Server removes the instance.

Message-driven beans should also perform some form of regular clean-up routine outside of the ejbRemove() method, because the beans cannot rely on ejbRemove() being called under all circumstances (for example, if the EJB throws a runtime exception).

Using the Message-Driven Bean Context

WebLogic Server calls setMessageDrivenContext() to associate the message-driven bean instance with a container context.This is not a client context; the client context is not passed along with the JMS message. WebLogic Server provides the EJB with a container context, whose properties can be accessed from within the instance by using the following methods from the MessageDrivenContext interface:

Implementing Business Logic with onMessage()

The message-driven bean's onMessage() method performs all of the business logic for the EJB. WebLogic Server calls onMessage() when the EJB's associated JMS Queue or Topic receives a message, passing the full JMS message object as an argument. It is the message-driven EJB's responsibility to parse the message and perform the necessary business logic in onMessage().

Make sure that the business logic accounts for asynchronous message processing. For example, it cannot be assumed that the EJB receives messages in the order they were sent by the client. Instance pooling within the container means that messages are not received or processed in a sequential order, although individual onMessage() calls to a given message-driven bean instance are serialized.

See javax.jms.MessageListener.onMessage() for more information.

Handling Exceptions

Message-driven bean methods should not throw an application exception or a RemoteException, even in onMessage(). If any method throws such an exception, WebLogic Server immediately removes the EJB instance without calling ejbRemove(). However, from the client perspective the EJB still exists, because future messages are forwarded to a new instance that WebLogic Server creates.

Transaction Services for Message-Driven Beans

As with other EJB types, message-driven beans can demarcate transaction boundaries either on their own (using bean-managed transactions), or by having the WebLogic Server container manage transactions (container-managed transactions). In either case, a message-driven bean does not receive a transaction context from the client that sends a message. WebLogic Server always calls a bean's onMessage() method by using the transaction context specified in the bean's deployment descriptor, as required by the EJB 2.0 specification.

Because no client provides a transaction context for calls to a message-driven bean, beans that use container-managed transactions must be deployed using the Required or NotSupported transaction attribute in ejb-jar.xml. Transaction attributes are defined in ejb-jar.xml as follows:

<assembly-descriptor>

  <container-transaction>

    <method>

      <ejb-name>MyMessageDrivenBeanQueueTx</ejb-name>

      <method-name>*</method-name>

    </method>

  <trans-attribute>NotSupported</trans-attribute>

  </container-transaction>

</assembly-descriptor>

Message Receipts

The receipt of a JMS message that triggers a call to an EJB's onMessage() method is not generally included in the scope of a transaction. For EJBs that use bean-managed transactions, the message receipt is always outside the scope of the bean's transaction, as described in the EJB 2.0 specification.

For EJBs that use container-managed transaction demarcation, WebLogic Server includes the message receipt as part of the bean's transaction only if the bean's transaction attribute is set to Required.

Message Acknowledgment

For message-driven beans that use container-managed transaction demarcation, WebLogic Server automatically acknowledges a message when the EJB transaction commits. If the EJB uses bean-managed transactions, both the receipt and the acknowledgment of a message occur outside of the EJB transaction context. WebLogic Server automatically acknowledges messages for EJBs with bean-managed transactions, but the deployer can configure acknowledgment semantics using the jms-acknowledge-mode deployment parameter.

Deploying Message-Driven Beans in WebLogic Server

To deploy a message-driven bean on WebLogic Server, you edit the XML file to create the deployment descriptors that associate the EJB with a configured JMS destination.

Deployment Descriptors

The deployment descriptor for a message-driven bean also specifies:

Deployment Elements

The EJB 2.0 specification adds the following new XML deployment elements for deploying message-driven beans.

These elements are defined in the ejb-jar.xml deployment file, as described in the EJB 2.0 specification. The following excerpt shows a sample XML stanza for defining a message-driven bean:

<enterprise-beans>

  <message-driven>

    <ejb-name>exampleMessageDriven1</ejb-name>

    <ejb-class>examples.ejb20.message.MessageTraderBean</ejb-class>

    <transaction-type>Container</transaction-type>

    <message-driven-destination>

      <jms-destination-type>

        javax.jms.Topic

      </jms-destination-type>

    </message-driven-destination>

    ...

  </message-driven>

  ...

</enterprise-beans>

In addition to the new ejb-jar.xml elements, the weblogic-ejb-jar.xml file includes a new message-driven-descriptor stanza to associate the message-driven bean with an actual destination in WebLogic Server.