Wednesday, December 06, 2006

Messaging Quickstart: Sample Code

The previous post described how to setup a Queue in Weblogic Server. This post shows the code necessary to run a Simple Messaging example using a servlet and Message Driven Bean. You can always implement an message listener instead of using a Message Driven Bean, but using MDBs is much cleaner and easier. Follow these steps to run the example
  1. Setup XDoclet
    1. Download XDoclet from here, and extract it.
    2. In Eclipse->Window->preferences, select xdoclet and set the Xdoclet home to the appropriate directory.
  2. Create the Message Driven Bean
    1. Create an EJB project in Eclipse.
    2. In the J2EE perspective, right-click on the Deployment descriptor and create a new Message Driven Bean. Eclipse generates the required classes and the ejb-jar.xml file with the new MDB definition in it. Modify the Bean to look like this
      public class MessagingExampleBean implements javax.ejb.MessageDrivenBean, javax.jms.MessageListener {
      private javax.ejb.MessageDrivenContext messageContext = null;
      public void setMessageDrivenContext(javax.ejb.MessageDrivenContext messageContext) throws javax.ejb.EJBException {
      this.messageContext = messageContext;
      }
      public void ejbCreate() {
      }
      public void ejbRemove() {
      messageContext = null;
      }
      public MessagingExampleBean() {
      }
      public void onMessage(javax.jms.Message message) {
      System.out.println("Message Driven Bean got message " + message);
      }
      }
      Add the following definitions to the ejb-jar.xml
      <?xml version="1.0" encoding="UTF-8"?>
      <ejb-jar version="2.1" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd">
      <display-name>MessagingExample</display-name>
      <enterprise-beans>
      <message-driven>
      <display-name>MessagingExampleMDB</display-name>
      <ejb-name>MessagingExampleMDB</ejb-name>
      <ejb-class>jms.MessagingExampleMdb</ejb-class>
      <transaction-type>Bean</transaction-type>
      <message-destination-type>javax.jms.Queue</message-destination-type>
      </message-driven>
      </enterprise-beans>
      <assembly-descriptor>
      <container-transaction>
      <method>
      <ejb-name>MessagingExampleMDB</ejb-name>
      <method-name>*</method-name>
      </method>
      <trans-attribute>Required</trans-attribute>
      </container-transaction>
      </assembly-descriptor>
      </ejb-jar>
    3. Create a new file weblogic-ejb-jar.xml. This is required for Weblogic bindings.
      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE weblogic-ejb-jar PUBLIC "-//BEA Systems, Inc.//DTD WebLogic 8.1.0 EJB//EN" "http://www.bea.com/servers/wls810/dtd/weblogic-ejb-jar.dtd">
      <weblogic-ejb-jar>
      <weblogic-enterprise-bean>
      <ejb-name>MessagingExampleMDB</ejb-name>
      <message-driven-descriptor>
      <pool>
      <max-beans-in-free-pool>5</max-beans-in-free-pool>
      <initial-beans-in-free-pool>5</initial-beans-in-free-pool>
      </pool>
      <destination-jndi-name>jms/testQueue</destination-jndi-name>
      <initial-context-factory>weblogic.jndi.WLInitialContextFactory</initial-context-factory>
      <connection-factory-jndi-name>jms/connectionFactory</connection-factory-jndi-name>
      <jms-polling-interval-seconds>20</jms-polling-interval-seconds>
      </message-driven-descriptor>
      <transaction-descriptor>
      <trans-timeout-seconds>3600</trans-timeout-seconds>
      </transaction-descriptor>

      </weblogic-enterprise-bean>
      </weblogic-ejb-jar>
  3. Create the Client. For this example, I used a servlet that simply sends a "Hello" message to the MDB through the Queue. Here is the code for it
    public class MessaginClientServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
    public final static String JNDI_FACTORY = "weblogic.jndi.WLInitialContextFactory";
    public final static String JMS_FACTORY = "weblogic.examples.jms.QueueConnectionFactory";
    public final static String QUEUE = "weblogic.examples.jms.exampleQueue";
    public MessaginClientServlet() {
    super();
    }
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    try {
    Context ctx = getInitialContext("t3://localhost:20001");
    QueueConnectionFactory qconFactory;
    QueueConnection connection;
    QueueSession session;
    QueueSender sender;
    Queue queue;
    TextMessage msg;

    qconFactory = (QueueConnectionFactory) ctx.lookup("jms/connectionFactory");
    connection = qconFactory.createQueueConnection();
    session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
    queue = (Queue) ctx.lookup("jms/testQueue");
    msg = session.createTextMessage();
    sender = session.createSender(queue);
    msg.setText("Hello World");
    connection.start();
    sender.send(msg);
    session.close();
    connection.close();
    } catch (Exception e) {
    e.printStackTrace();
    }
    }

    private InitialContext getInitialContext(String url) throws NamingException {
    Hashtable<String, String> env = new Hashtable<String, String>();
    env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
    env.put(Context.PROVIDER_URL, url);
    return new InitialContext(env);
    }
    }

7 comments:

  1. Hey, this post rocks. It saved my head at work!!! :) :) :) :)

    ReplyDelete
  2. Hi,
    while I sending message from client i m facing following error,

    javax.naming.CommunicationException [Root exception is java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is:
    java.io.EOFException]
    at weblogic.jrmp.Context.lookup(Context.java:189)
    at weblogic.jrmp.Context.lookup(Context.java:195)
    at javax.naming.InitialContext.lookup(Unknown Source)
    at JMSClient.sendToQueue(JMSClient.java:41)
    at JMSClient.main(JMSClient.java:26)
    Caused by: java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is:
    java.io.EOFException
    at sun.rmi.transport.tcp.TCPChannel.createConnection(Unknown Source)
    at sun.rmi.transport.tcp.TCPChannel.newConnection(Unknown Source)
    at sun.rmi.server.UnicastRef.newCall(Unknown Source)
    at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
    at weblogic.jrmp.Context.lookup(Context.java:185)
    ... 4 more
    Caused by: java.io.EOFException
    at java.io.DataInputStream.readByte(Unknown Source)
    ... 9 more


    Thanks in advance,

    Rahul.

    ReplyDelete
  3. Hi, Have you been able to solve that javax.naming.CommunicationException.
    I have the same thing.
    Thanks,
    Alex

    ReplyDelete
  4. Kudos to Abhi. Thanks for simplifying simple things.
    This is an exellent article. People tried reading the weblogic article 100 times and they don't get how to create a simple Queue and QueueConenction factory and MDB. Though I created in activeMQ and others easily, this weblogic JMS Queue's documentation especially for JMS on BEA server is confusing enough for any level of professional. Suggestion to Bea(oh, now it is Oracle right), to incorporate this link in their documentation.

    ReplyDelete
  5. Really good article from implementation prospective. Thanks .
    You have given good example by which we developer can gain confidance by practicaly doing the things rather than simply reading the theory.

    ReplyDelete
  6. Whats the resolution for the above menitoned error

    ReplyDelete
  7. Hi Frens,

    I tried working on this sample code but couldnt run it fine.

    Can anyone please elaborate what are the next steps after done with all coding (what to run and how). I am very new to JMS.

    Thanks and Cheers,

    ReplyDelete

Popular Posts