Skip Headers
Oracle® Containers for J2EE Enterprise JavaBeans Developer's Guide
10g Release 3 (10.1.3)
B14428-01
  Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
Next
Next
 

Accessing an EJB 2.1 MDB

A client never accesses an MDB directly: rather, the client accesses an MDB by sending a message through the JMS destination (queue or topic) associated with the MDB.

This section describes:

Sending a Message to a JMS Destination Using EJB 2.1

To send a message to a JMS destination using EJB 2.1:

  1. Look up both the JMS destination (queue or topic) and its connection factory.

    You can look up these resources using a predefined logical name (see "Configuring an Environment Reference to a JMS Destination or Connection Resource Manager Connection Factory") or the explicit JNDI name you defined when you configured your JMS provider (see "Configuring an EJB 2.1 MDB to Use a Non-J2CA Message Service Provider").

    Oracle recommends that you use logical names as shown in this procedure and its examples.

  2. Use the connection factory to create a connection.

    If you are receiving messages for a queue, then start the connection.

  3. Create a session over the connection.

  4. Use the retrieved JMS destination to create a sender for a queue or a publisher for a topic.

  5. Create the message.

  6. Send the message using either the queue sender or the topic publisher.

  7. Close the queue session.

  8. Close the connection.

Example 29-24 shows how a servlet client sends a message to a queue.

Example 29-25 shows how a JSP client sends a message over a topic.

Example 29-24 Servlet Client Sends Message to a Queue

public final class testResourceProvider extends HttpServlet
{
  private String resProvider = "myResProvider";
  private HashMap msgMap = new HashMap();
  Context ctx = new InitialContext();

 public void doGet(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException
 {
    doPost(req, res);
 }

 public void doPost(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException
 {
   // Retrieve the name of the JMS provider from the request, which is to be used in creating
   // the JNDI string for retrieval
    String rp = req.getParameter ("provider");
    if (rp != null) resProvider = rp;

    try
    {
      // 1a. Look up the Queue Connection Factory
      QueueConnectionFactory qcf = (QueueConnectionFactory)
              ctx.lookup (
                  "java:comp/resource/" + resProvider + "/QueueConnectionFactories/myQCF"
              ); 
      // 1b. Lookup the Queue
      Queue queue = (Queue)
              ctx.lookup (
                  "java:comp/resource/" + resProvider + "/Queues/rpTestQueue"
              );
      
      // 2a. Create queue connection using the connection factory.
      QueueConnection qconn = qcf.createQueueConnection();
      // 2a. We're receiving msgs, so start the connection.
      qconn.start();

      // 3. create a session over the queue connection.
      QueueSession sess = qconn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);

       // 4. Since this is for a queue, create a sender on top of the session. 
       //This is used to send out the message over the queue.
      QueueSender snd = sess.createSender (q);

    drainQueue (sess, q);
    TextMessage msg = null;

    /* Send msgs to queue.  */
    for (int i = 0; i < 3; i++)
    {
      // 5. Create message
      msg = sess.createTextMessage();
      msg.setText ("TestMessage:" + i);

      // Set property of the recipient to be the MDB
      // and set the reply destination.
      msg.setStringProperty ("RECIPIENT", "MDB");
      msg.setJMSReplyTo(q);
      
      //6. send the message using the sender.
      snd.send (msg);

      // You can store the messages IDs and sent-time  in a map (msgMap),
      // so that when messages are received, you can verify if you 
      // *only* received those messages that you were
      // expecting. See receiveFromMDB() method where msgMap gets used
      msgMap.put( msg.getJMSMessageID(), new Long (msg.getJMSTimestamp()) );
    }

    // receive a reply from the MDB.
    receiveFromMDB (sess, q);

     //7. Close sender, session, and connection for queue
     snd.close();
     sess.close();
     qconn.close();
    }
    catch (Exception e)
    {
      System.err.println ("** TEST FAILED **"+ e.toString());
      e.printStackTrace();
    }
    finally
    {
    }
 }

  /*
   * Receive any msgs sent to us via the MDB
   */
  private void receiveFromMDB (QueueSession sess, Queue q)
    throws Exception
  {
    // The MDB sends out a message (as a reply) to this client. The MDB sets
    // the receipient as CLIENT. Thus, we will only receive msgs that have 
    // RECIPIENT set to 'CLIENT'
    QueueReceiver rcv = sess.createReceiver (q, "RECIPIENT = 'CLIENT'");

    int nrcvd = 0;
    long trtimes = 0L;
    long tctimes = 0L;
    // First msg needs to come from MDB. May take  a little while 
    //Receiving Messages
    for (Message msg = rcv.receive (30000); msg != null; msg = rcv.receive (30000))
    {
      nrcvd++;
      String rcp = msg.getStringProperty ("RECIPIENT");

      // Verify if msg in message Map  
      // We check the msgMap to see if this is the message that we are expecting.
      String corrid = msg.getJMSCorrelationID();
      if (msgMap.containsKey(corrid))
      {
        msgMap.remove(corrid);
      }
      else
      {
        System.err.println ("** received unexpected message [" + corrid + "] **");
      }
    }
    rcv.close();
  }

  /*
   * Drain messages from queue
   */
  private int drainQueue (QueueSession sess, Queue q)
    throws Exception
  {
    QueueReceiver rcv = sess.createReceiver (q);
    int nrcvd = 0;

    // First drain any old msgs from queue
    for (Message msg = rcv.receive(1000); msg != null; msg = rcv.receive(1000))
      nrcvd++;

    rcv.close();

    return nrcvd;
  }
}

Example 29-25 JSP Client Sends Message to a Topic

<%@ page import="javax.jms.*, javax.naming.*, java.util.*" %>
<%
//1a. Lookup the MessageBean topic
jndiContext = new InitialContext();
topic = (Topic)jndiContext.lookup("rpTestTopic");

//1b. Lookup the MessageBean Connection factory
topicConnectionFactory = (TopicConnectionFactory) jndiContext.lookup("myTCF");

//2 & 3. Retrieve a connection and a session on top of the connection
topicConnection = topicConnectionFactory.createTopicConnection();
topicSession = topicConnection.createTopicSession(true,Session.AUTO_ACKNOWLEDGE);

//5. Create the publisher for any messages destined for the topic
topicPublisher = topicSession.createPublisher(topic);

//6. Send out the message
for (int  ii = 0; ii < numMsgs; ii++)
{
  message = topicSession.createBytesMessage();
  String  sndstr = "1::This is message " + (ii + 1) + " " + item;
  byte[]  msgdata = sndstr.getBytes();
  message.writeBytes(msgdata);
  
  topicPublisher.publish(message);
  System.out.println("--->Sent message: " + sndstr);
}

//7. Close publisher, session, and connection for topic
topicPublisher.close();
topicSession.close();
topicConnection.close();
%>
Message sent!

Sending a Message to a J2CA Destination Using EJB 2.1

To send a message to a J2CA destination using EJB 2.1:

  1. Look up both the J2CA connection factory.

    You can look up this resource using a predefined logical name (see "Configuring an Environment Reference to a JMS Destination or Connection Resource Manager Connection Factory") or the explicit JNDI name you defined when you configured your JMS provider (see "Configuring an EJB 2.1 MDB to Use a Non-J2CA Message Service Provider").

    Oracle recommends that you use logical names as shown in this procedure and its examples.

  2. Obtain a javax.resource.cci.ConnectionFactory.

    If the EIS is a JMS message service provider, there will likely be connection factory choices for queue or topic. For example, the Oracle JMS Connector offers a QueueConnectionFactory and a TopicConnectionFactory.

  3. Use the factory to obtain a javax.resource.cci.Connection.

  4. Use the connection to obtain a javax.resource.cci.Interaction.

  5. Configure the interaction and use Interaction method execute to send the message.