HomeDigital EditionSys-Con RadioSearch Java Cd
Advanced Java AWT Book Reviews/Excerpts Client Server Corba Editorials Embedded Java Enterprise Java IDE's Industry Watch Integration Interviews Java Applet Java & Databases Java & Web Services Java Fundamentals Java Native Interface Java Servlets Java Beans J2ME Libraries .NET Object Orientation Observations/IMHO Product Reviews Scalability & Performance Security Server Side Source Code Straight Talking Swing Threads Using Java with others Wireless XML
 

"Using the Java Messaging Service with
 Enterprise JavaBeans"
Vol 5 Issue 6, p.60

	

Lisiting 1 

package jdj.article.jmsejb; 

import javax.naming.*; 
import javax.jms.*;          // Import the javax.jms package 
import java.util.Hashtable; 

 * JmsQueueManager.java 
 * 
 * An abstract base class that implements all the basic 
 * functionality for creating a JMS QueueReceiver or 
 * QueueSender. Includes all the necessary code for obtaining 
 * a JNDI naming Context, looking up the Queue and retrieving 
 * it, setting up the JMS Connection and Session,and creating 
 * the actual QueueReceiver and/or QueueSubscriber. 
 * 
 * This is extended by the ReceiverStartup and the 
 * JMSEjbClient classes, but it could also be used in a "has 
 * a" relationship by creating an implementation class and 
 * then contained as an attribute of our classes through a 
 * reference. 
 * 
 * @author Scott Grant 
 * @version 1.0 - 4/10/00 
 * 
public abstract class JmsQueueManager implements IJmsEjbConstants 
{ 
    protected QueueConnectionFactory queueFx;  // Our factory 
    protected QueueConnection conn;        // Our connection 
    protected Queue queue;                     // Our queue 
    protected Queue tempQueue;        // Our temporary queue 
    protected QueueSession session;           // Our session 
    protected QueueReceiver receiver;         / Our receiver 
    protected QueueSender sender;              // Our sender 
  
    protected String jndiFactory; 
    protected String url; 
    protected String jmsFactory; 
    protected String queueName; 
    protected String principal; 
    protected String credential; 
  
    protected Context ctx;  // our initial JNDI context 
  
 * Obtain an initial context from Weblogic through JNDI (this 
 * will be used to access the JMS factory and topic/queue 
 * information). 

 public JmsQueueManager(String jndiFactory, String url, 
                      String queueName, String jmsFactory, 
                      String principal, String credential) 
    { 
        this.jndiFactory = jndiFactory; 
        this.url = url; 
        this.queueName = queueName; 
        this.jmsFactory = jmsFactory; 
        this.principal = principal; 
        this.credential = credential; 
    } 
  
 protected void finalize() throws Throwable 
 { 
     closeJMS(); 
 } 
  
 protected Context getInitialContext() 
 { 
     // Try and create a new initial context using our 
     // properties... 
        Hashtable env = new Hashtable(); 
        env.put(Context.INITIAL_CONTEXT_FACTORY, jndiFactory); 
        env.put(Context.PROVIDER_URL, url); 
        env.put(Context.SECURITY_AUTHENTICATION, "simple"); 
        env.put(Context.SECURITY_PRINCIPAL, principal); 
        env.put(Context.SECURITY_CREDENTIALS, credential); 
        try 
        { 
            // Try and create a new initial context using 
            // our properties... 
            Context context = new InitialContext(env); 
            return context; 
        } 
        catch(NamingException e) 
        { 
            System.out.println("getInitialContext: Could not 
            obtain initial naming context"); 
            e.printStackTrace(); 
            return null; 
        } 
        catch(Exception e) 
        { 
            System.out.println("getInitialContext: Unknown 
        exception trying to obtain initial naming context"); 
            e.printStackTrace(); 
            return null; 
        } 
 } 
  
 * Initialize JMS - create initial JMS resources, 
 * start connection, etc. 

 protected void initializeJMS(String type, MessageListener 
 listener, boolean transacted) 
 { 
     try 
     { 
         if (ctx == null) 
             ctx = getInitialContext(); 
  
         if (ctx != null) 
         { 
  
             // Get the default queue connection 
             // factory...Destinations (Queues and 
             // Topics) and ConnectionFactory objects are 
             // administered objects - you retreive them 
             // from the Weblogic Application Server via JNDI. 
             queueFx = (QueueConnectionFactory) 
             ctx.lookup(jmsFactory); 

                // Get a QueueConnection from the QueueCon- 
                // nectionFactory 
                conn = queueFx.createQueueConnection(); 

                // Get a QueueSession - auto-acknowledge - 
                // and use the parameter to 
                // determine if it is transacted or not... 
                session = conn.createQueueSession(transact- 
                ed, Session.AUTO_ACKNOWLEDGE); 

                // Get the Queue from JNDI...Queue is an 
                // administered object 
                queue = (Queue) ctx.lookup(queueName); 

 
                if ((type.equals(RECEIVER) || 
                    type.equals(SENDER_RECEIVER)) && 
                    listener != null) 
                { 
                    // Create a Receiver for the Queue... 
                    receiver = session.createReceiver(queue); 
  
                    // Set the listener (this class) 
                    receiver.setMessageListener(listener); 
                } 
  
                if (type.equals(SENDER) || 
                type.equals(SENDER_RECEIVER)) 
                { 
                    sender = session.createSender(queue); 
                } 
                // Start connection... 
                conn.start(); 
         } 
         else 
         { 
             System.out.println("initializeJMS: InitialCon- 
             text was null"); 
             return; 
         } 
     } 
     catch(NamingException e) 
     { 
         System.out.println("initializeJMS: NamingException 
         was thrown"); 
            e.printStackTrace(); 
     } 
     catch(JMSSecurityException e) 
     { 
         System.out.println("initializeJMS: JMSSecurityExcep- 
         tion was thrown"); 
            e.printStackTrace(); 
     } 
     catch(JMSException e) 
     { 
         System.out.println("initializeJMS: JMSException was 
         thrown"); 
            e.printStackTrace(); 
     } 
     catch(Exception e) 
     { 
         System.out.println("initializeJMS: Unknown exception 
         trying to obtain initialize JMS"); 
            e.printStackTrace(); 
     } 
 } 
  
 * Close down JMS - stop the connection, etc. 

 protected void closeJMS() 
 { 
     if (conn != null) 
        { 
            try 
            { 
                conn.stop(); 
                if (sender != null) 
                    sender.close(); 
  
                if (receiver != null) 
                    receiver.close(); 
  
                if (session != null) 
                    session.close(); 
  
                conn.close(); 
            } 
            catch(JMSException e) 
            { 
                System.out.println("closeJMS: JMSException 
                thrown while trying to close connections"); 
                e.printStackTrace(); 
            } 
            catch(Exception e) 
            { 
                System.out.println("closeJMS: An unknown 
      exception occurred while trying to close connections"); 
                e.printStackTrace(); 
            } 
        } 
 } 
  
 * sendMessage 
 * 
 * Send a JMS Message. 

 protected void sendMessage(Message msg) 
 { 
     try 
     { 
         msg.setJMSDeliveryMode(DeliveryMode.PERSISTENT); 
         sender.send(msg); // default behavior 
     } 
     catch(JMSException e) 
     { 
         System.out.println("initializeJMS: JMSException try- 
         ing to send message to queue"); 
     } 
 } 
  
 * createMapMessage 
 * 
 * Creates a MapMessage - delegates to 
 * the session version of this method. 
  
 protected MapMessage createMapMessage() 
 { 
     try 
     { 
         return session.createMapMessage(); // default behavior 
     } 
     catch(JMSException e) 
     { 
         System.out.println("createMapMessage: JMSException 
         trying to create MapMessage"); 
     } 
  
     return null; 
 } 
  
 // You could implement all the additional "createXXXMes0 
 // sage()" delegator methods here, if you wanted to flesh 
 // out this class... 

} 

Listing 2 
package jdj.article.jmsejb; 

import javax.naming.*; 
import javax.jms.*;          // Import the javax.jms package 
import javax.ejb.*; 
import java.util.*; 
import java.lang.reflect.*; 
import java.rmi.RemoteException; 

import weblogic.common.*; 

 * JmsEjbReceiver.java 
 * 
 * Implements Weblogic Start-Up class that receives JMS 
 * Messages on an incoming Queue using Weblogic's JMS 
 * implementation. 
 * 
 * @author Scott Grant 
 * @version 1.0 - 4/10/00 

public class ReceiverStartup extends JmsQueueManager 
                               implements MessageListener, 
                                           T3StartupDef 
{ 
  
    // Note: These parameters could be passed in the Hashtable 
    // arguments to the Weblogic Start-Up Class via the 
    // "weblogic.properties" file...I have hard coded them here... 
    public static final String JNDI_FACTORY = 
    "weblogic.jndi.WLInitialContextFactory"; 
    public static final String URL = "t3://localhost:7001"; 
    public static final String JMS_FACTORY = 
    "javax.jms.QueueConnectionFactory"; 
    public static final String QUEUE = 
    "jdj.article.jmsejb.ejbMessageQueue"; 
    public static final String PRINCIPAL = "system"; 
    public static final String CREDENTIAL = "password"; 
  
    private T3ServicesDef serv; // Part of Weblogic Start-Up 
    class support 
  
    public ReceiverStartup() 
    { 
        super(JNDI_FACTORY, URL, QUEUE, JMS_FACTORY, PRINCI- 
        PAL, CREDENTIAL); 
    } 
  
    // Weblogic Start-Up Class 
  
    public void setServices(T3ServicesDef s) 
    { 
        serv = s; 
    } 

    * startup 
    * 
    * This is part of the Weblogic T3StartupDef 
    * interface 
    * 
    public String startup(String name, Hashtable args) throws 
    Exception 
    { 
        ctx = getInitialContext(); 
  
        if (ctx != null) 
            initializeJMS(RECEIVER, this, false);   // Not 
            using transactions 
        else 
            throw new NamingException("ReceiverStartup - 
            initializeJMS: Naming Exception was thrown"); 
  
  
        return "ReceiverStartup listening..."; 
    } 
  
    // JMS Items 
    * Implements the onMessage method of the MessageListener 
    * interface. This is the call back method used by JMS to 
    * pass us messages on the queue our which we're 
    * registered with... 
  
 public void onMessage(Message msg) 
 { 
     System.out.println("ReceiverStartup: Received incoming 
     JMS message..."); 
  
        try 
        { 
            String msgType = msg.getJMSType(); 
            if (msg instanceof MapMessage && 
            msgType.equals(JMSEJB_MESSAGE)) 
            { 
              MapMessage mapMsg = (MapMessage)msg; 
              String homeName = mapMsg.getString("HomeName"); 
              String createName = mapMsg.getString("CreateName"); 
              int createParams = mapMsg.getInt("CreateParams"); 
              String methodName = mapMsg.getString("MethodName"); 
              int methodParams = mapMsg.getInt("MethodParams"); 
  
              System.out.println("homeName: " + homeName); 
  
              if (ctx == null) 
                 ctx = getInitialContext(); 
  
              if (ctx != null) 
                { 
                   try 
                   { 
                      // Get the class type and parameters 
                      // for the EJBHome create method... 
                        System.out.println("Getting create 
                        class types..."); 
 Class[] createTypes = get  ClassTypesFromMessage((MapMessage)msg,
 createParams, "CreateParam", "CreateParamType"); 
                        System.out.println("Getting create 
                        arguments and types..."); 
 Object[] createArgs = getArgumentsFromMessage((MapMessage)msg,
 reateParams, "CreateParam", "CreateParamType"); 
  
                        // Get the class type and parame- 
                        // ters for the EJBObject (stub) 
                        // method to invoke... 
                        System.out.println("Getting method 
                        class types..."); 
  Class[] methodTypes = getClassTypesFromMessage((MapMessage)msg,
  ethodParams, "MethodParam", "MethodParamType"); 
                        System.out.println("Getting method 
                        arguments and types..."); 
  Object[] methodArgs = getArgumentsFromMessage((MapMessage)msg,
  methodParams, "MethodParam", "MethodParamType"); 
  
                        System.out.println("Looking up object class name..."); 
  
                        // Find our home class through JNDI... 
                        Object obj = ctx.lookup(homeName); 
                        Class homeClass = obj.getClass(); 
  
                        // Find the create method... 
                        Method methodCreate = 
               homeClass.getMethod(createName, createTypes); 
  
                        System.out.println("Invoking create 
                        method..."); 
  
                        // Invoke the create method... 
                        Object ejb = 
                      methodCreate.invoke(obj, createArgs); 
  
                        System.out.println("Invoking method 
                        " + methodName + "..."); 
  
                        // Find the EJB method in the JMS 
                        // Message... 
                        Method methodCall = ejb.get- 
                 Class().getMethod(methodName, methodTypes); 
  
                        // Invoke the EJB method... 
                        methodCall.invoke(ejb, methodArgs); 
  
                    } 
                    catch(InvocationTargetException e) 
                    { 
                        System.out.println("ReceiverStart- 
                 up: InvocationTargetException was thrown"); 
                    } 
                    catch(NoSuchMethodException e) 
                    { 
                        System.out.println("ReceiverStart- 
                    up: NoSuchMethodException was thrown"); 
                    } 
                    catch(IllegalAccessException e) 
                    { 
                        System.out.println("ReceiverStart- 
                   up: IllegalAccessException was thrown"); 
                    } 
                    catch(Exception e) 
                    { 
                        System.out.println("ReceiverStart- 
                            up: An exception was thrown"); 
                    } 
                } 
                else 
                    System.out.println("ReceiverStartup: 
       onMessage: Failed to obtain initial naming context"); 
            } 
        } 
        catch (JMSException e) 
        { 
            System.out.println("ReceiverStartup: onMessage: 
                              JMSException was thrown"); 
            e.printStackTrace(); 
        } 
    } 
  
    * getClassTypesFromMessage 
    * 
    * Returns an array of Class types from a MapMessage 
    * which contains a list of parameters for an EJB method call. 
  
    public Class[] getClassTypesFromMessage(MapMessage msg, 
    int params, 
        String argName, String typeName) throws JMSException 
    { 
        Class[] types = new Class[0]; 
  
        if (params > 0) 
        { 
            types = new Class[params]; 
  
            for (int i = 0; i < params; i++) 
            { 
                String type = msg.getString(typeName + i); 
                if (type.equals("String")) 
                { 
                    types[i] = String.class; 
                } 
                else if (type.equals("int")) 
                { 
                    types[i] = int.class; 
                } 
                else if (type.equals("long")) 
                { 
                    types[i] = long.class; 
                } 
                else if (type.equals("float")) 
                { 
                    types[i] = float.class; 
                } 
                else if (type.equals("double")) 
                { 
                    types[i] = double.class; 
                } 
                else if (type.equals("short")) 
                { 
                    types[i] = short.class; 
                } 
                else if (type.equals("byte")) 
                { 
                    types[i] = byte.class; 
                } 
                else if (type.equals("object")) 
                { 
                    // Extract any type of object... 
                    Object obj = msg.getObject(argName + i); 
                    types[i] = obj.getClass(); 
                    System.out.println("Object instance: " 
                    + obj.getClass().getName()); 
                } 
                else if (type.equals("message")) 
                { 
                    types[i] = Message.class; 
                } 
                else 
                    System.out.println("Unknown parameter 
                    type"); 
            } 
        } 
  
        return types; 
    } 
  
    * getArgumentsFromMessage 
    * 
    * Returns an array of Object's from a JMS MapMessage 
    * that are extracted as parameters for an EJB method 
    * call. 

    public Object[] getArgumentsFromMessage(MapMessage msg, int params, 
         String argName, String argType) throws JMSException 
    { 
        Object[] args = new Object[0]; 
  
        if (params > 0) 
        { 
            args = new Object[params]; 
  
            for (int i = 0; i < params; i++) 
            { 
                String type = msg.getString(argType + i); 
                if (type.equals("String")) 
                { 
                    String temp = msg.getString(argName + i); 
                    args[i] = temp; 
                } 
                else if (type.equals("int")) 
                { 
                    int temp = msg.getInt(argName + i); 
                    args[i] = new Integer(temp); 
                } 
                else if (type.equals("long")) 
                { 
                    long temp = msg.getLong(argName + i); 
                    args[i] = new Long(temp); 
                } 
                else if (type.equals("float")) 
                { 
                    float temp = msg.getFloat(argName + i); 
                    args[i] = new Float(temp); 
                } 
                else if (type.equals("double")) 
                { 
                    double temp = msg.getDouble(argName + i); 
                    args[i] = new Double(temp); 
                } 
                else if (type.equals("short")) 
                { 
                    short temp = msg.getShort(argName + i); 
                    args[i] = new Short(temp); 
                } 
                else if (type.equals("byte")) 
                { 
                    byte temp = msg.getByte(argName + i); 
                    args[i] = new Float(temp); 
                } 
                else if (type.equals("object")) 
                { 
                    Object obj = msg.getObject(argName + i); 
                    args[i] = obj; 
                } 
                else if (type.equals("message")) 
                { 
                    args[i] = msg; 
                } 
                // You could add other types here...Object,etc... 
                else 
                    System.out.println("Unknown parameter type"); 
            } 
        } 
  
        return args; 
    } 
} 

Listing 3 

package jdj.article.jmsejb; 
  
import javax.jms.*; 
import javax.naming.*; 
  
* JmsEjbClient 
* 
* This is our client class. It extends the base JmsQueueMan- 
* ager to handle the creation of the JMS connection, session, 
* and QueueSender. 
* 
* It creates two JMS MapMessages. The first is sent to the 
* EJB's "onMessage" method through simple delegation. The 
* second message is actually used to call a method on the EJB 
* asynchronously via a JMS message - both cases are handled 
* by the ReceiverStartup Weblogic startup class. 
* 
* @author Scott Grant 
* @version 1.0 - 4/10/00 
  
public class JmsEjbClient extends JmsQueueManager 
{ 
    public static final String JNDI_FACTORY = 
    "weblogic.jndi.WLInitialContextFactory"; 
    public static final String URL = "t3://localhost:7001"; 
    public static final String JMS_FACTORY = 
    "javax.jms.QueueConnectionFactory"; 
    public static final String QUEUE = 
    "jdj.article.jmsejb.ejbMessageQueue"; 
    public static final String PRINCIPAL = "system"; 
    public static final String CREDENTIAL = "password"; 
  
    public JmsEjbClient() 
    { 
        super(JNDI_FACTORY, URL, QUEUE, JMS_FACTORY, PRINCI 
        PAL, CREDENTIAL); 
    } 
  
    public static void main(String[] args) 
    { 
        JmsEjbClient client = new JmsEjbClient(); 
        client.initializeJMS(SENDER, null, false); 
  
        MapMessage msg = client.createMapMessage(); 
        try 
        { 
            // Create a MapMessage and send it to the Queue 
            msg.setJMSType(JMSEJB_MESSAGE); 
            msg.setString("HomeName", 
            "jdj.article.jmsejb.JmsEjbExampleHome"); 
            msg.setString("CreateName", "create"); 
            msg.setInt("CreateParams", 0); 
  
            // We are sending this method to the "onMessage" 
            // method of the EJB, so we set one parameter 
            // which is of type "message". This is a special 
            // case and the ReceiverStartup will interpret 
            // this as delegation - it will pass the actual 
            // JMS Message itself, on to this method (onMes- 
            // sage) of the EJB as the parameter. 
            msg.setString("MethodName", "onMessage"); 
            msg.setInt("MethodParams", 1); 
            msg.setString("MethodParamType0", "message"); 
            msg.setString("StringMessage", "This is my test 
       message string sent to the EJB onMessage method..."); 
  
            client.sendMessage(msg); 
  
            // Now send a method invocation with Params... 
  
            msg = client.createMapMessage(); 
            msg.setJMSType(JMSEJB_MESSAGE); 
            msg.setString("HomeName", 
            "jdj.article.jmsejb.JmsEjbExampleHome"); 
            msg.setString("CreateName", "create"); 
            msg.setInt("CreateParams", 0); 
  
            // We are sending this message to ReceiverStart- 
            // up as a method 
            // invocation. So we set the method name, and 
            // the parameter types, and values. The 
            // ReceiverStartup class will use Java's reflec- 
            // tion mechanism to find this method on the 
            // EJB, and invoke it, passing 
            // in the parameters as we've specified them. 
            // This demonstrates using a Weblogic startup 
            // class as a delegator for asynchronous 
            // method invocation on an EJB... 
            msg.setString("MethodName", "testMethod"); 
            msg.setInt("MethodParams", 2); 
            msg.setString("MethodParamType0", "int"); 
            msg.setInt("MethodParam0", 1); 
            msg.setString("MethodParamType1", "String"); 
            msg.setString("MethodParam1", "This is my test message string sent to the EJB
			 testMethod as method parameter..."); 
  
            client.sendMessage(msg); 
        } 
        catch(JMSException e) 
        { 
            System.out.println("JmsEjbClient: JMSException was thrown"); 
        } 
    } 
} 



 

All Rights Reserved
Copyright ©  2004 SYS-CON Media, Inc.
  E-mail: [email protected]

Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. SYS-CON Publications, Inc. is independent of Sun Microsystems, Inc.