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, createParams, "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, methodParams, "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");
}
}
}
No comments:
Post a Comment