JMS and EJB 2.0

With EJB 2.0 specification Sun introduced a new EJB type, the message-driven bean. This bean type was introduced to specifically address the prior lack of integration with JMS that we were forced to work around in our EJB 1.1 example, through the use a delegation model and a WebLogic Startup class.

The EJB 2.0 message-driven bean solves this problem for us. The message-driven bean type now provides a mechanism implemented through the EJB container, for dealing with asynchronous message delivery to an EJB.

In this section we'll show how to create an EJB 2.0 message-driven bean that can be used in place of StdMailBean to achieve the same functionality as demonstrated in the EJB 1.1 example application.

A message-driven bean is stateless (and can only be stateless - there are no other options, though it should be noted that it is not a session bean - a message-driven bean is its own interface type, which only extends the default EJB interface EnterpriseBean), and has these important features:

  • It implements the MessageDrivenBean interface.

  • It does not have a home interface (as the developer of a MessageDrivenBean you do not need to create a home interface for the bean). Since this bean type is accessed only by the container in response to JMS messages, there is no home interface for this type of bean.

  • It does not have a remote interface (as above, as the developer, you don't need to create a remote interface for this type of bean). As above, since this bean type is never accessed remotely by a client, and is only used internally by the EJB container in response to asynchronous JMS message delivery, there is no remote interface.

The following diagram shows the architecture of a message-driven bean:

click to expand

As you can see in the above diagram, a message-driven bean receives JMS messages asynchronously through the EJB container. The deployment descriptor properties for the EJB specify whether the bean is associated with a topic or a queue and whether or not it is a durable subscription. A given message-driven bean can only be associated with one JMS destination. You can change this through the deployment descriptor properties, but once deployed, it may only be associated with a single queue or topic. The WebLogic server's deployment file, weblogic-ejb-jar.xml is used to associate a given message-driven bean with a specific topic or queue name - this destination type must exist in the application server.

The Case Logging System with EJB 2.0

Using a message-driven bean, we can simplify our initial application design significantly. Since we no longer need to delegate requests to our bean, we no longer need a WebLogic Startup class. The development of the EJB is simplified as well, since we no longer need to provide the home interface or the remote interface. From the perspective of the client, however, the message-driven bean acts as any other JMS consumer, and the client isn't aware of any difference.

So how does this change the way in which the application works? We will reduce the complexity of our implementation by removing the WebLogic Startup class, and turning our EJB 1.1 stateless session bean into an EJB 2.0 message-driven bean. It's important to note that the same underlying complexity still exists, although now the majority of this will be handled by the EJB container. The EJB container will now intercept the asynchronously delivered JMS message, and locate and invoke the message-driven bean's onMessage() method. From an implementation standpoint, though, we have now made things much simpler by creating our message-driven bean. The following sequence diagram shows the changes:

click to expand

As you can see, our front end stays the same, but we have removed the WebLogic Startup class and consolidated our functionality into a message-driven bean called MailBean that will perform the same functions as our EJB 1.1 bean.

Implementing the EJB 2.0 MailBean

We will now present the source code that contains the changes to our application. Since the JSPs are unchanged, we will focus only on the message-driven bean. We will create a new Java package called com.acme.ejb.messagedriven and create a new bean class implementation under this package called MailBean.java.

Next, we will create two new deployment XML files, ejb-jar.xml and weblogic-ejb-jar.xml, for deploying our EJB 2.0 bean. By building and deploying this new bean to the server we can demonstrate the new functionality through application since this bean also acts as a durable subscriber on the same MailTopic that we used in our first example.

The MailBean Class

The MailBean class implements the MessageDrivenBean interface. As you can see, the rest of the bean is for the most part identical to the StdMailBean's bean implementation class. One important point, though, is that it also implements the JMS MessageListener interface. Whereas 1.1 EJBs cannot implement the MessageListener interface directly, the new MessageDrivenBean type must implement the MessageListener interface.

Since our message-driven bean implements almost identical code to our StdMailBean, we will only show the differences between the two. First, you'll notice we jump straight into the bean class description. This is because our EJB home and remote interfaces are not part of a message-driven bean. Our class implements two interfaces:

  • MessageDrivenBean - Our bean type.

  • Messagelistener - A message-driven bean class must implement the JMS MessageListener interface and its onMessage() method.

     package com.acme.ejb.messagedriven;     import java.io.IOException;     import java.util.*;     import javax.ejb.*;     import javax.jms.*;     import javax.naming.*;     import javax.activation.DataHandler;     import javax.mail.*;     import javax.mail.internet.*;     import java.rmi.RemoteException;     public class MailBean implements MessageDrivenBean, MessageListener {       private static final boolean VERBOSE = true;       private static final String MAIL_HOST = "mail.smtp.host";       private static final String MAIL_SUBJECT = "Help Request";       private static final String JNDI_MAIL = "acme/Mail";       private MessageDrivenContext context;       private String message;       public void ejbRemove () {}       public void ejbCreate () throws CreateException {} 

We implement the setMessageDrivenContext() method that is part of the MessageDrivenBean interface. We also create an attribute of type MessageDrivenContext and set it. This is where you can retrieve the bean's EJBContext information.

       public void setMessageDrivenContext (MessageDrivenContext ctx) {          context = ctx;       } 

Finally, you can see that we implement the onMessage() method of the MessageListener interface directly in the bean class. This will be called whenever an asynchronous JMS message is delivered to our EJB. The code in this method is nearly the same, as the code in StdMailBean. The only difference is that the method returns void instead of boolean. The bean will extract the message body content, and create and send an e-mail alert message:

       public void onMessage(javax.jms.Message msg) {         .         .         .       }       public boolean sendMail(String to, String subject.                               String body, boolean debug) {         .         .         .       }       public javax.mail.internet.InternetAddress[]            parseEmailAddress(String addresses) {         .         .         .       }       private void packageBody(javax.mail.Message msg, String body)           throws MessagingException, java.io.IOException {         .         .         .       }       private String createBody(String problem, String name, String location)       {         .         .         .         buf.append("This mail is from MailBean\n");       } 

Note 

We will also need the ByteArrayDataSource class again, but be sure to update the package directive.

The Deployment Descriptors

To properly package our EJB we again need to create the bean's deployment descriptor file. The ejb-jar.xml file contains the EJB specification's deployment descriptor tags, and references the EJB 2.0 DTD. We also have to create the file weblogic-ejb-jar.xml for archive. This file contains specific properties for fully configuring and registering the EJB in the WebLogic server environment.

ejb-jar.xml

The ejb-jar.xml file is much the same as our previous example. It uses the EJB 2.0 DTD, as you can see in the <!DOCTYPE > reference, and includes support for a new message-driven bean tag:

     <?xml version="1.0" encoding="Cp1252"?>     <!DOCTYPE ejb-jar PUBLIC"-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans     2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd">     <ejb-jar>       <enterprise-beans>         <message-driven>           <ejb-name>MailBean</ejb-name>           <ejb-class>com.acme.ejb.messagedriven.MailBean</ejb-class>           <transaction-type>Container</transaction-type>           <message-driven-destination>             <jms-destination-type>javax.jms.Topic</jms-destination-type>             <subscription-durability>durable</subscription-durability>           </message-driven-destination>           <resource-ref>              <description>description</description>              <res-ref-name>mail/MailSession</res-ref-name>              <res-type>javax.mail.Session</res-type>              <res-auth>Container</res-auth>           </resource-ref>         </message-driven>       </enterprise-beans>       <assembly-descriptor>         <container-transaction>           <method>             <ejb-name>MailBean</ejb-name>             <method-name>*</method-name>           </method>           <trans-attribute>NotSupported</trans-attribute>         </container-transaction>       </assembly-descriptor>     </ejb-jar> 

The tags to note here are:

  • The <message-driven> tag begins the description of a message-driven bean and its properties

  • The <message-driven-destination> tag wraps the properties of the type of destination the bean is associated with

  • The <jms-destination-type> tag contains the type of destination the bean is associated with, either javax.jms.Topic or javax.jms.Queue

  • The <subscription-durability> tag specifies whether or not the subscription is durable or non-durable

The weblogic-ejb-jar.xml Descriptor

Recall that along with the standard deployment descriptor information required by the EJB specification in the ejb-jar.xml file, the WebLogic server also requires its own information for deploying the EJB within the WebLogic server environment. The weblogic-ejb-jar.xml file for our Message-driven bean implementation looks as follows:

     <?xml version="1.0" encoding="Cp1252"?>     <!DOCTYPE weblogic-ejb-jar PUBLIC "-//BEA Systems, Inc.//DTD WebLogic 6.0.0     EJB//EN" "http://www.bea.com/servers/wls600/dtd/WebLogic-ejb-jar.dtd">     <weblogic-ejb-jar>       <weblogic-enterprise-bean>         <ejb-name>MailBean</ejb-name>         <message-driven-descriptor>           <pool>             <max-beans-in-free-pool>200</max-beans-in-free-pool>             <initial-beans-in-free-pool>20</initial-beans-in-free-pool>           </pool>           <destination-jndi-name>               com.acme.jms.topics.MailTopic           </destination-jndi-name>         </message-driven-descriptor>         <reference-descriptor>             <resource-description>                <res-ref-name>mail/MailSession</res-ref-name>                <jndi-name>mail/Session</jndi-name>             </resource-description>           </reference-descriptor>         <jndi-name>MailBean</jndi-name>       </weblogic-enterprise-bean>     </weblogic-ejb-jar> 

This file contains one tag of importance as far as we're concerned, in regard to our message-driven bean:

  • The <destination-jndi-name> tag is used to associate the bean with a named destination. This is the name of the queue or topic that you have created in the WebLogic server for your destination.

Deploying the EJB 2.0 Application

The process is nearly identical to that of the EJB 1.1 version. This time however, the directory structure need only be:

     com/         acme/              ejb/                  messagedriven/                                ByteArrayDataSource.class                                StdMail.class                                StdMailBean.class                                StdMailHome.class     META-INF/              ejb-jar.xml              weblogic-ejb-jar.xml 

Again package these files into an EJB JAR and run weblogic.ejbc on them.

Important 

Before you can run the EJB 2.0 example, you must install the EJB 2.0 beta patch for WebLogic 6.0. At the time of writing, EJB 2.0 is only in a proposed-final draft stage so WebLogic must be manually updated with a new JAR file that can be downloaded from the WebLogic website.

Now, when you run the application again you should receive two mails, one from each bean version.



Professional JMS
Professional JMS
ISBN: 1861004931
EAN: 2147483647
Year: 2000
Pages: 154

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net