Skip Headers

Oracle® Containers for J2EE Enterprise JavaBeans Developer's Guide 10g Release 3 (10.1.3) B14428-01 |
| Home | Solution Area | Contents | Index

Previous | 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

- Sending a Message to a J2CA Destination Using EJB 2.1

## 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.