/*
* @(#)HelloWorldMessageJNDI.java 1.6 05/03/29
*
* Copyright (c) 2001-2003 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
================================================================================
@(#)README 1.15 08/04/05
================================================================================
HelloWorldMessageJNDI example
Description
-----------
This example demonstrates a simple end-to-end "Hello World" JMS example that
can be compiled and run with the Sun Java(tm) System Message Queue product. The
test program uses Java Naming and Directory Interface (JNDI) to lookup
administered objects, sends and receives a JMS "Hello World" message via a Queue
destination.
This example is also the companion example used in the "Administration Console
Tutorial" (Chapter 4 of the MQ Administrator's Guide). The "Administration
Console Tutorial" focuses more on the Administration Console GUI; this README
contains instructions that use the command line tool imqobjmgr.
This example demonstrates the following:
- How to create and store MQ administered objects in a file based object
store using the MQ imqobjmgr tool.
- A simple "Hello World" JMS Application:
- How to use the JNDI APIs to lookup MQ administered objects in a file
based object store.
- Sending and receiving JMS messages.
- How to compile the JMS application.
- How to run the JMS application.
Files
-----
HelloWorldMessageJNDI.java Source file for this example.
*.class Prebuilt Java class files for this example.
add_cf.props imqobjmgr command file for creating
Connection Factory object.
add_q.props imqobjmgr command file for creating
Queue object.
delete_cf.props imqobjmgr command file for deleting
Connection Factory object.
delete_q.props imqobjmgr command file for deleting
Queue object.
list.props imqobjmgr command file for listing MQ
administered objects.
README This file.
JMS/MQ background
-----------------
Every JMS application that sends and/or receives messages needs access to at
least 2 JMS administered objects:
Connection Factory object
Destination object
The Connection Factory object is used by the application to connect to the JMS
provider (MQ broker). The Destination object is used to identify the relevant
destination on the JMS provider, for example when sending or receiving messages.
Each JMS provider (like MQ) has it's own implementation of the above objects
which encapsulate provider-specific implementation and configuration
information.
This example uses the Queue messaging domain which means that the specific
object types the example will deal with are:
Connection Factory object (javax.jms.ConnectionFactory)
Queue Destination object (javax.jms.Queue)
The above 2 objects can be directly instantiated by the JMS application. For
example:
cf = new com.sun.messaging.ConnectionFactory();
(com.sun.messaging.ConnectionFactory is an object that is of type
javax.jms.ConnectionFactory)
However, this makes the application not portable across JMS vendors. To make
a JMS application truly portable, the objects should be stored in an object
store and JNDI should be used to look them up. The fact that the objects used
here are MQ specific will be completely transparent to the application if JNDI
is used. These objects can also be shared by multiple applications that need
access to the same MQ brokers and destinations.
Having all the JMS applications use administered objects in one object store
also makes management a little easier - compare this to the case where every JMS
application each instantiated it's own administered objects; managing which MQ
broker or destination each application uses can become difficult as the
complexity and size of the application grows.
MQ provides the object manager utility/tool (imqobjmgr) to manage (add, delete,
list, query, or update) MQ administered objects in an object store. To create
an administered object, imqobjmgr accepts the following information:
- The command/action that is needed: add
- The type of object in question e.g. Topic, Queue, Connection Factory,
etc.
- Attributes/properties of the object.
- Location of object store. This is specified as JNDI properties.
- JNDI lookupname of object in object store
Details on how the above information is specified to imqobjmgr is explained in
the Sun Java(tm) System Message Queue Administrator's Guide. It can also be seen
as part of imqobjmgr usage help:
imqobjmgr -H
To ease the running of this example, imqobjmgr command files will be used.
imqobjmgr allows you to specify the name of a command file that uses java
property file syntax to represent all or part of the imqobjmgr subcommand
clause. Using a command file with imqobjmgr is especially useful to specify
object store attributes, which are likely to be the same across multiple
invocations of imqobjmgr and which normally require a lot of typing. Command
files can help reduce errors caused by typos on the command line. Using a
command file can also allow you to avoid a situation in which you might
otherwise exceed the maximum number of characters allowed for the command line.
So instead of typing:
imqobjmgr add
-t q
-l "MyQueue"
-o "imqDestinationName=MyQueueDest"
-j java.naming.factory.initial=com.sun.jndi.fscontext.RefFSContextFactory
-j java.naming.provider.url=file:///C:/Temp
(all on one line)
you only need to type:
imqobjmgr -i add_q.props
(where add_q.props is a command file)
Each command file that is a part of this example will contain sufficient
documentation to show what the full imqobjmgr command line is required to
perform the equivalent action.
The format or syntax of the imqobjmgr command/input file is described in
the Sun Java(tm) System Message Queue Administrator's Guide.
Specifying the object Store: JNDI Properties
--------------------------------------------
The imqobjmgr tool uses JNDI to manage the object store. The object store
is specified to imqobjmgr via various JNDI properties. The most commonly
used JNDI properties here are:
- java.naming.factory.initial (Initial Context Factory)
The initial context factory is used to specify which JNDI service
provider you wish to use for your object store; for example, the
file system, LDAP or some other JNDI service provider.
The value to use for a file system object store is:
com.sun.jndi.fscontext.RefFSContextFactory
The value to use for an LDAP based object store is:
com.sun.jndi.ldap.LdapCtxFactory
- java.naming.provider.url (Provider URL)
This is the property for specifying the URL or location of
your object store. The provider URL value is dependent on what
service provider was specified for java.naming.factory.initial.
For a file system object store, an example value for this is:
file:///C:/Temp
or
file:///tmp
The directory specified for a file system object store must
already exist and must be accessible by the application or
tool using it.
For an LDAP based object store, an example value for this is:
ldap://myldaphost:389/ou=mqobjs, o=myapplication
Configuring the environment
---------------------------
To recompile or run this example, you need to set CLASSPATH
to include at least:
jms.jar
imq.jar
fscontext.jar
directory containing this example
A detailed guideline on setting CLASSPATH is found in the README
file in the jms demo subdirectory as well as in the "Quick Start
Tutorial" in the Sun Java(tm) System Message Queue Developer's Guide.
The following are examples for setting CLASSPATH on the different
platforms. These commands are run from the directory containing
this example.
On Solaris:
setenv CLASSPATH /usr/share/lib/jms.jar:/usr/share/lib/imq.jar:
/usr/share/lib/fscontext.jar:.
On Windows:
set CLASSPATH=%IMQ_HOME%\lib\jms.jar;%IMQ_HOME%\lib\imq.jar;
%IMQ_HOME%\lib\fscontext.jar:.
On Linux:
setenv CLASSPATH /opt/sun/mq/share/lib/jms.jar:
/opt/sun/mq/share/lib/imq.jar:/opt/sun/mq/share/lib/fscontext.jar:.
#####hpux-dev#####
On HP-UX:
export CLASSPATH=/opt/sun/mq/share/lib/jms.jar:
/opt/sun/mq/share/lib/imq.jar:/opt/sun/mq/share/lib/fscontext.jar:.
Note that it is assumed that the above export command is run on
BASH shell
Building the example
--------------------
Run the following:
javac HelloWorldMessageJNDI.java
Running the example
-------------------
Here are the steps for running this example:
1. Verify object store file location.
2. Create the Connection Factory administered object.
3. Create the Queue administered object.
4. Start the MQ broker.
5. Run the JMS application.
6. Cleanup
1. Verify object store file location
------------------------------------
This example uses the file system object store. The directory that
is used by default is C:/Temp. This is a path that is commonly
available on the Windows platform. This path is used as the value
for the JNDI provider URL for the object store. The provider URL
that is specified has the following syntax:
file:///C:/Temp
If this path is not available for use (for example, if you are running
on a Solaris machine), you need to:
- Modify the value of the objstore.attrs.java.naming.provider.url
property in all the imqobjmgr command files (*.props). They already
have a commented out entry that specifies the /tmp directory on
Solaris as an example of how to configure this property differently.
- (This is to be done later) Run the sample application with the new
provider URL for example:
java HelloWorldMessageJNDI file:///tmp
2. Create the Connection Factory administered object
----------------------------------------------------------
To create the connection factory object, run the following:
imqobjmgr -i add_cf.props
3. Create the Queue administered object
---------------------------------------
To create the queue object, run the following:
imqobjmgr -i add_q.props
Optional:
After creating the Connection Factory and Queue objects,
you can verify that they exist by listing them:
imqobjmgr -i list.props
4. Start the broker
-------------------
The command for starting the broker is:
imqbrokerd
Run the above command in a separate command (or terminal) window.
5. Run the JMS application
--------------------------
To run the sample application, run the following command:
java HelloWorldMessageJNDI
or
java HelloWorldMessageJNDI file:///tmp
if you need to specify an alternate provider URL (object store location).
As noted above, the default is file:///C:/Temp
You should see the following output:
Using file:///C:/Temp for Context.PROVIDER_URL
Looking up Connection Factory object with lookup
name: MyConnectionFactory
Connection Factory object found.
Looking up Queue object with lookup name: MyQueue
Queue object found.
Creating connection to broker.
Connection to broker created.
Publishing a message to Queue: MyQueueDest
Received the following message: Hello World
6. Cleanup
----------
Once you are done with the example, you can optionally delete the administered
objects created by running:
imqobjmgr -i delete_cf.props
imqobjmgr -i delete_q.props
You will be prompted for confirmation - respond with 'y'.
Useful URLs
-----------
MQ main product page:
http://sun.com/software/message_queue
MQ documentation page:
http://docs.sun.com/db/prod/s1.s1msgqu#hic
A better understanding of JNDI and how java objects are stored can be found
in the JNDI tutorial at:
http://java.sun.com/products/jndi/tutorial/index.html
Some of the relevant sections of the JNDI tutorial:
Java Objects and the Directory
http://java.sun.com/products/jndi/tutorial/objects/index.html
Tips for LDAP Users
http://java.sun.com/products/jndi/tutorial/ldap/index.html
LDAP Security
http://java.sun.com/products/jndi/tutorial/ldap/security/index.html
This will explain the usage of these properties:
java.naming.security.authentication
java.naming.security.principal
java.naming.security.credentials
/*
* @(#)HelloWorldMessageJNDI.java 1.6 05/03/29
*
* Copyright (c) 2001-2003 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
/*
* Simple message producer and consumer which obtains its ConnectionFactory
* and Queue from Administered Objects using a JNDI lookup.
*
* This example requires two administered objects to be stored before it
* will work.
*
* 1. A ConnectionFactory Object stored with a lookup name of
* ``MyConnectionFactory''
* 2. A Queue Object stored with a lookup name of ``MyQueue''
*
* The initial context factory is configured in this example to use the File
* Store (an alternative would be to use LDAP). The provider url (where
* the file store is located) is defined by default to be C:/Temp
* This is a Windows specific path.
* When running this example on Unix, the first command line parameter
* must be set to the Unix directory url where the File Store has been created.
* e.g. file:///tmp on Solaris/Linux.
*
* What this means is that an MQ Object Store should be created (via imqadmin
* or imqobjmgr) at C:/Temp. When that store is created the following JNDI
* Naming Service Properties should be set (via the imqadmin or imqobjmgr):
*
* java.naming.provider.url = file:///C:/Temp
* java.naming.factory.initial = com.sun.jndi.fscontext.RefFSContextFactory
*
* If this example is run on Solaris/Linux, use the following value instead
*
* java.naming.provider.url = file:///tmp
*
* If you have turned off auto-creation of destinations on the MQ broker
* then a physical Queue destination matching the destination name used
* in the queue administered object needs to be created on the broker.
* That is best accomplished by using the Administration Console.
*
* For this example to compile and run the following must be
* in your CLASSPATH (in addition to the directory containing this example):
*
* jms.jar, imq.jar, fscontext.jar (these are located in IMQ_HOME/lib)
*/
import javax.naming.*;
import javax.jms.ConnectionFactory;
import javax.jms.Connection;
import javax.jms.Session;
import javax.jms.MessageProducer;
import javax.jms.MessageConsumer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.DeliveryMode;
import javax.jms.TextMessage;
import javax.jms.JMSException;
import java.util.*;
public class HelloWorldMessageJNDI {
static String def_windows_url = "file:///C:/Temp";
static String def_unix_url = "file:///tmp";
String MYCF_LOOKUP_NAME = "MyConnectionFactory";
String MYQUEUE_LOOKUP_NAME = "MyQueue";
ConnectionFactory cf;
Connection connection;
Session session;
MessageProducer msgProducer;
MessageConsumer msgConsumer;
Queue queue;
TextMessage msg,
rcvMsg;
public static void main(String args[]) {
String url = def_windows_url;
if (args.length > 0) {
url = args[0];
}
System.out.println("\nUsing "
+ url
+ " for Context.PROVIDER_URL");
HelloWorldMessageJNDI simple_client = new HelloWorldMessageJNDI(url);
}
public HelloWorldMessageJNDI(String url) {
Hashtable env;
Context ctx = null;
env = new Hashtable();
// Store the environment variables that tell JNDI which initial context
// to use and where to find the provider.
// For use with the File System JNDI Service Provider
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.fscontext.RefFSContextFactory");
env.put(Context.PROVIDER_URL, url);
try {
// Create the initial context.
ctx = new InitialContext(env);
} catch (NamingException ne) {
System.err.println("Failed to create InitialContext.");
System.err.println("The Context.PROVIDER_URL used/specified was: " + url);
System.err.println("Please make sure that the path to the above URL exists");
System.err.println("and matches with the objstore.attrs.java.naming.provider.url");
System.err.println("property value specified in the imqobjmgr command files:");
System.err.println("\tadd_cf.props");
System.err.println("\tadd_q.props");
System.err.println("\tdelete_cf.props");
System.err.println("\tdelete_q.props");
System.err.println("\tlist.props\n");
usage();
System.err.println("\nThe exception details:");
ne.printStackTrace();
System.exit(-1);
}
System.out.println("");
try {
// Lookup my connection factory from the admin object store.
// The name used here here must match the lookup name
// used when the admin object was stored.
System.out.println("Looking up Connection Factory object with lookup name: "
+ MYCF_LOOKUP_NAME);
cf = (javax.jms.ConnectionFactory) ctx.lookup(MYCF_LOOKUP_NAME);
System.out.println("Connection Factory object found.");
} catch (NamingException ne) {
System.err.println("Failed to lookup Connection Factory object.");
System.err.println("Please make sure you have created the Connection Factory object using the command:");
System.err.println("\timqobjmgr -i add_cf.props");
System.err.println("\nThe exception details:");
ne.printStackTrace();
System.exit(-1);
}
System.out.println("");
try {
// Lookup my queue from the admin object store.
// The name I search for here must match the lookup name used when
// the admin object was stored.
System.out.println("Looking up Queue object with lookup name: "
+ MYQUEUE_LOOKUP_NAME);
queue = (javax.jms.Queue)ctx.lookup(MYQUEUE_LOOKUP_NAME);
System.out.println("Queue object found.");
} catch (NamingException ne) {
System.err.println("Failed to lookup Queue object.");
System.err.println("Please make sure you have created the Queue object using the command:");
System.err.println("\timqobjmgr -i add_q.props");
System.err.println("\nThe exception details:");
ne.printStackTrace();
System.exit(-1);
}
System.out.println("");
try {
System.out.println("Creating connection to broker.");
connection = cf.createConnection();
System.out.println("Connection to broker created.");
} catch (JMSException e) {
System.err.println("Failed to create connection.");
System.err.println("Please make sure that the broker was started.");
System.err.println("\nThe exception details:");
e.printStackTrace();
System.exit(-1);
}
System.out.println("");
try {
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// Create the MessageProducer and MessageConsumer
msgProducer = session.createProducer(queue);
msgConsumer = session.createConsumer(queue);
// Tell the provider to start sending messages.
connection.start();
msg = session.createTextMessage("Hello World");
// Publish the message
System.out.println("Publishing a message to Queue: " + queue.getQueueName());
msgProducer.send(msg, DeliveryMode.NON_PERSISTENT, 4, 0);
// Wait for it to be sent back.
rcvMsg = (TextMessage) msgConsumer.receive();
System.out.println("Received the following message: " + rcvMsg.getText());
connection.close();
} catch (JMSException e) {
System.err.println("JMS Exception: " + e);
e.printStackTrace();
System.exit(-1);
}
}
private static void usage() {
System.err.println("Usage: " +
"\tjava HelloWorldMessageJNDI [Context.PROVIDER_URL]\n" +
"\nOn Unix:\n\tjava HelloWorldMessageJNDI " + def_unix_url +
"\nOn Windows:\n\tjava HelloWorldMessageJNDI " + def_windows_url);
}
}
|