Sunday, May 27, 2012

Message Driven Bean in EJB3.0



A message-driven bean is an enterprise bean that allows J2EE applications to process messages asynchronously. The client does not receive a response to a message from the MDB.
  1. A client will send a message to a queue or topic.
  2. The message is then retrieved and processed by MDB.


The Java EE server uses Java Message Service (JMS) to support MDBs. Many of the details of JMS are hidden, making the use of MDBs easier. MDBs are managed by the server EJB container. The EJB container will treat all instances of the same MDB class identically.



There are two common techniques in JMS API for structuring an MDB application:

  • Point-to-Point: One or more producers will send messages to a queue. These messages are then consumed by one or more consumers (MDBs). Once removed from a queue it is no longer available to other consumers.
  • Publish/Subscribe: One or more producers will send messages to a topic. Each message in the topic will then be sent to each consumer (MDB) that is currently subscribing to the topic.


The creation of an MDB involves three tasks:

  1. Using the @MessageDriven annotation to designate the class as an MDB
  2. Implementing the javax.jms.MessageListener interface for JMS-driven beans
  3. Overriding the onMessage method

The MDB must be defined as public and cannot be declared as final or abstract. In addition, it
needs a public default constructor and cannot have a finalize method.



I am going to write a simple MDB and configure it as point to point in Jboss 5.0 GA.

MyEJB3TextMDB.java

package com.sarf.ejb3.bean;

import java.util.Scanner;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

@MessageDriven(mappedName="jms/textQueue", activationConfig = {
  @ActivationConfigProperty(propertyName = "destinationType", 
                            propertyValue = "javax.jms.Queue"),
  @ActivationConfigProperty(propertyName = "destination", 
                            propertyValue = "jms/textQueue") })

public class MyEJB3TextMDB implements MessageListener
{
      public MyEJB3TextMDB(){
      }
     
      @Override
      public void onMessage(Message message) {
            TextMessage textMessage = (TextMessage) message;
            try {
                  Scanner scanner = new Scanner(textMessage.getText());
                  System.out.println("Text Message received.");
                  System.out.println("Message is : "+scanner.next());
                  } catch (JMSException e) {
                        throw new RuntimeException(e);
                  }
      }
}



The process of connecting to a queue and sending a message to the queue involves:
  1. Establishing a connection using the Connection object
  2. Creating a Session object that represents the communications between the servlet and the queue.  It is also used to send the message.
  3. Creating a MessageProducer object to create the Message


TextMessageController.java

package com.sarf.ejb3.controller;

import java.io.IOException;
import javax.annotation.Resource;
import javax.jms.Connection;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.QueueConnectionFactory;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class TextMessageController extends HttpServlet {
      private static final long serialVersionUID = 1L;
     
      @Resource(mappedName="jms/textQueue")
      private Queue queue;
      @Resource(mappedName="java:/ConnectionFactory")
      private QueueConnectionFactory queueConnectionFactory;
          
      public TextMessageController() {super();}

      protected void doGet(HttpServletRequest request, 
           HttpServletResponse response)
           throws ServletException, IOException {
      }
      
      protected void doPost(HttpServletRequest request, 
       HttpServletResponse response) throws ServletException, IOException {
     
            Connection connection;
            try {
                  connection = queueConnectionFactory.createConnection();
                  Session session =  
                  connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
                  MessageProducer messageProducer = (MessageProducer) 
                  session.createProducer(queue);
                       
                  TextMessage textMessage = session.createTextMessage();
                  textMessage.setText("Yow!!!");
                  messageProducer.send(textMessage);
                  System.out.println("Text Message Sent !!!");
                 }catch(Exception e){}
                 
                  RequestDispatcher rd = 
                   request.getRequestDispatcher("./jsp/out.jsp");
                   rd.forward(request, response);
         }
 }




index.jsp



out.jsp




web.xml








To configure JMS Queue in  JBoss Enterprise Application Platform, we can configure in two different ways: 
1. Copy and paste this file(my-destination-service.xml) in jboss-5.1.0.GA\server\default\deploy directory.
2. Copy and paste the content of this file into jboss-5.1.0.GA\server\default\deploy\messaging\destination-service.xml file.

 
my-destination-service.xml










We will use ant build tool to compile and create an ear file in given structure image.
You can download the sample build.xml used for this project. Click Here