Sams Teach Yourself BEA WebLogic Server 7.0 in 21 Days
Consider an EJB scenario. EJBs are designed to be used in a synchronous environment. To include the facility of asynchronous messaging in the enterprise bean scenario, message-driven beans were introduced in the EJB2.0 specification. The functions of message-driven beans are a combination of the EJB and JMS functionalities. The obvious question that would arise is, what's so special about message-driven beans? Why shouldn't you use a pure JMS application, in case you need an asynchronous functionality? Well, to develop a sturdy, full-scale JMS application, you have to handle transactions, security, scalability, fault tolerance, concurrent message processing, and object life cycle. This is a pretty daunting task. However, all these are inbuilt into the EJB server, which makes your development much simpler and allows you to concentrate on your business functionality rather than the technology. As is clear from the previous paragraph, message-driven beans are managed by the vendor server's EJB container. A message-driven bean is always a message recipient. Similarly, in the WebLogic Server's sender-recipient model, a message-driven bean is analogous to a message recipient. The WebLogic Server creates listeners to these queues at deployment time. Because these message-driven beans are container managed, the WebLogic Server automatically manages the removal and creation of message-driven beans so as to process other incoming messages. Using the onMessage() method in your message-driven bean, you can obtain the obtain messages from a destination. This is done with the support of deployment descriptor files. The details of this are explained a little further in the life cycle description of a message-driven bean. You do not write a remote or home interface for message-driven beans because message-driven beans follow the asynchronous model, and both these interfaces are strictly synchronous by definition. A message-driven bean connects to the JMS server using the "run-as" principle. The run-as element, set in the deployment descriptor file ejb-jar.xml, is used by the bean as an identity to interact with the JMS. The default value for this element is guest. The destination type (queue or topic) is also specified in the deployment descriptor in the destination-type element. In message-driven beans, permission to receive must be set in order to connect to either a remote destination or a destination in the same domain. To set the "receive" permission, an ACL (access control list) must be used. As explained in the earlier days, an ACL is a list of users or a group that has permission to access specific resources. The "receive" permission has to be granted to the ACL in the domain in which the message-driven bean is executed. Although the functionality of message-driven beans makes them look very similar to the JMS destination's message consumer, there are many differences between the two:
Life Cycle of a Message-Driven Bean
When a message reaches the destination queue or topic, the WebLogic Server first obtains a new bean instance. The max-beans-in-free-pool parameter is used to obtain a new bean instance. If no instance is available because the maxbeans element value is equal to the max-beans-in-free-pool value (that is, because all the free beans in the pool have been taken up), the WebLogic Server waits until an instance is freed. If it gets a bean instance immediately, that instance is used. If the max-beans-in-free-pool element value is not equal to the maxbeans element value and no instances of the bean are available in the free pool, the WebLogic Server creates a new instance by calling the ejbCreate() method. The MessageDrivenContext of the bean is then set using the setMessageDrivenContext() method, associating this instance with a container context. The bean can use the getRollBackOnly(), setRollBackOnly(), and getUserTransaction() methods of the container context. The former two can be used only for container-managed transactions, while the last can be used for bean-managed transactions. The getCallerPrincipal() method and isCallerInRole() method should not be called by an instance of a message-driven bean. When the destination associated with the bean receives a message, the WebLogic Server calls the bean's onMessage() method and executes the business functionality implemented in this method. Example Message-Driven Bean
Listing 15.5 shows a sample code snippet for a message-driven bean called SampleMessageDrivenBean. Listing 15.5 SampleMessageDrivenBean
public class SampleMessageDrivenBean implements MessageDrivenBean, MessageListener{ public void ejbCreate(){ System.out.println("EJB create called"); } public void ejbRemove(){ System.out.println("EJB remove called"); } public void onMessage(Message inMessage) { TextMessage msg = null; try { if (inMessage instanceof TextMessage) { msg = (TextMessage) inMessage; System.out.println ("MESSAGE BEAN: Message received: " + msg.getText()); } else { System.out.println ("Message of wrong type: " + inMessage.getClass().getName()); } } catch (JMSException e) { e.printStackTrace(); mdc.setRollbackOnly(); } catch (Throwable te) { te.printStackTrace(); } } Listing 15.6 contains a sample snippet of the corresponding deployment descriptor file, ejb-jar.xml. Listing 15.6 ejb-jar.xml
<assembly-descriptor> <container-transaction> <method> <ejb-name>SampleMessageDrivenBean</ejb-name> <method-name>*</method-name> </method> <trans-attribute>NotSupported</trans-attribute> </container-transaction> </assembly-descriptor> Listing 15.7 shows a sample snippet of the corresponding entries in the weblogic-ejb-jar.xml file. Listing 15.7 weblogic-ejb-jar.xml
<message-driven-descriptor> <destination-jndi-name>...</destination-jndi-name> <provider-url>WeblogicURL:Port</provider-url> </message-driven-descriptor> ... <stateless-session-descriptor> <pool> <max-beans-in-free-pool>500</max-beans-in-free-pool> <initial-beans-in-free-pool>250</initial-beans-in-free-pool> </pool> </stateless-session-descriptor> Message-Driven Bean Tips
Keep the following points in mind while developing your message-driven bean:
|