tags:

views:

699

answers:

3

As I understand it, a J2EE container is required to include a JMS provider. Is it possible for a standalone Java application to send messages to a JMS queue provided by the container? If so, how do I access the JNDI lookups from outside the container?

(I am trying this with Geronimo if it makes any difference, but I am hoping there is a standard way of doing this.)

A: 

You can place messages in a JMS queue without an application server.

However, you'll need to know how to get to the JMS provider directly -- without using JNDI, since that is provided by the JavaEE application server.

dustmachine
+3  A: 

You should be able to create an InitialContext that uses the JNDI server in Geronimo. You can then use this to lookup your JMS Connection Factory and Queue.

The following example was adapted from http://forums.sun.com/thread.jspa?threadID=5283256 to use the Geronimo JNDI Factory.

Context                  jndiContext = null;
ConnectionFactory   connectionFactory = null;
Connection             connection = null;
Session                  session = null;
Queue                    queue = null;
MessageProducer     messageProducer = null;   

try
{
    //[1] Create a JNDI API InitialContext object.
    Hashtable properties = new Hashtable(2);

    // CHANGE these to match Geronimos JNDI service

    properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.RemoteInitialContextFactory");
    properties.put(Context.PROVIDER_URL, "ejbd://127.0.0.1:4201");
    jndiContext = new InitialContext(properties);

    //[2] Look up connection factory and queue.
    connectionFactory = (ConnectionFactory)jndiContext.lookup("jms/ConnectionFactory");
    queue = (Queue)jndiContext.lookup("jms/Queue");

    //[3]
    // - Create connection
    // - Create session from connection; false means session is not transacted.
    // - Create sender and text message.
    // - Send messages, varying text slightly.
    connection = connectionFactory.createConnection();
    session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
    messageProducer = session.createProducer(queue);

   //send a message
   TextMessage message = session.createTextMessage(this.jTextSend.getText()); 
   messageProducer.send(message); 

   //example for send some object
   //ObjectMessage message = session.createObjectMessage();
   //MyObj myObj = new MyObj ("Name"); //this class must be serializable 
   //message.setObject(myObj );
   //messageProducer.send(message);
}
catch(Exception ex)
{
   LOG.error(ex);
}
finally
{
     if(connection !=null)
     {
         try
         {
             connection.close();
         }
         catch(JMSException e)
         {
              LOG.error(e);
         }
     }
}
pjp
You might want to add that this assumes you have a local JNDI running.
Robin
A: 

You can do it, and there may be multiple ways depending on the thin client that is accessing the queue. The example given by @pjp will work providing you have the correct jar files for accessing the server in question, including a jar which will provide your application with a JNDI instance. These jars should be provided by the vendor, and may include instructions on how to connect without using JNDI as well. Although I think the JNDI method is the simplest and keeps coding consistent both on and off the server.

Each vendor will have different jars to provide client access, in IBM's case, they are different for the internal JMS provider vs. WebSphere MQ (since they are two different implementations).

Robin