Administered Objects

Administered objects are objects pre-configured and stored by JMS administrators for the use of JMS clients. These objects are normally stored in the namespace of a naming and directory service provider and are available to the JMS clients for standard JNDI lookup. The implementation classes for Administered objects are required to implement java.io.Serializable and javax.naming. Referencable interfaces so that they can be stored in standard JNDI naming contexts.

Administered objects contain configuration information required by JMS clients for connecting to the JMS provider, local addressing information for message destinations, etc. JMS providers normally provide tools for creating, configuring, and storing administered objects. JMS defines two kinds of administered objects:

  • Connection factories are administered objects used by JMS clients for creating connections to a JMS provider

  • Destination objects are used by JMS clients to specify the locations to and from which they send and receive messages

Connection Factories

Connection factories contain configuration information defining the host on which the provider is running, the port on which it is listening, client identifiers for the connections, etc. JMS providers provide vendor-specific tools for configuring connection factories and specifying the different properties associated with connection factories. JMS doesn't define standard ways for defining these properties against connection factories.

Connection factories are defined in JMS using the interface javax.jms.ConnectionFactory. This interface doesn't define any methods, but acts as the root interface for the connection factory interfaces specific to the two messaging models.

The interfaces javax.jms.QueueConnectionFactory and javax.jms.TopicConnectionFactory define the methods required for connection factories used in the PTP messaging model and Pub/Sub messaging model respectively. JMS providers supply the implementation classes for the aforementioned interfaces.

Important 

Portable JMS clients should be using only the standard JMS interfaces in the application code and should not be using the provider-specific implementation classes. Connection factories form the basis for writing vendor-neutral JMS applications.

The QueueConnectionFactory Interface

Connections used in the PTP messaging model are called queue connections. Queue connection factories provide factory methods for creating queue connections. The interface javax.jms.QueueConnectionFactory defines the methods required for queue connection factories.

This interface defines two methods for creating queue connections. The first method creates a queue connection with the default security credentials for the JMS client:

     public javax.jms.QueueConnection createQueueConnection() throws                                              JMSException, JMSSecurityException 

The second method lets the client specify the user name and password when they create the connection:

     javax.jms.QueueConnection createQueueConnection(                        java.lang.String user, java.lang.String password)                                throws JMSException, JMSSecurityException 

JMS doesn't define the specifics for security authentication. Currently this aspect is very much specific to the JMS provider you use. Both the aforementioned methods throw javax.jms.JMSException on any internal server error and javax.jms.JMSSecurityException on failing to authenticate the client.

The TopicConnectionFactory Interface

Connections used in the Pub/Sub messaging model are called topic connections. Topic connection factories provide factory methods for creating topic connections. The interface javax.jms.TopicConnectionFactory defines the methods required for topic connection factories.

This interface defines two methods for creating topic connections. The first method creates a topic connection with the default security credentials for the JMS client:

     public javax.jms.TopicConnection createTopicConnection() throws                                        JMSException, JMSSecurityException 

The second method lets the client specify the user name and password when they create the connection:

     public javax.jms.TopicConnection createTopicConnection(                                 java.lang.String user, Java.lang.String password)                                         throws JMSException, JMSSecurityException 

JMS doesn't define the specifics for security authentication. Currently this aspect is very much specific to the JMS provider you use. Both the aforementioned methods throw javax.jms.JMSException on any internal server error and javax.jms.JMSSecurityException on failing to authenticate the client.

Destinations

Destination objects contain the provider-specific addressing information required by the JMS clients for sending and receiving messages. Destination objects are created, configured, and stored in a namespace by JMS administrators for the use of JMS clients. The interface javax.jms.Destination is the root interface for different types of Destination objects.

The interfaces javax.jms.Queue and javax.jms.TemporaryQueue define the methods required for destination objects used in the PTP messaging model and javax.jms.Topic and javax.jms.TemporaryTopic define those required for the Pub/Sub messaging model.JMS providers supply implementation classes for all the aforementioned interfaces.

Portable JMS clients should never use these provider-specific implementation classes in their application code and should use only the standard JMS interfaces. Destinations should be looked up using standard JNDI method calls and casting the looked up object reference to the required destination interface. For example:

     InitialContext ctx = new InitialContext();     Queue queue = (Queue)ctx.lookup("myQueue"); 

Queues

Queues are specialized Destination objects used in PTP messaging. Messages sent to a queue obey the classic FIFO (First-In, First-Out) rule. Every message in PTP messaging can have one, and only one, receiver. Queues are defined in JMS using the interface javax.jms.Queue.JMS providers supply implementation classes for this interface, which can be created, configured, and stored in a namespace by the JMS administrator and can be later looked up by JMS clients. Queues can also be created using queue sessions. Queue sessions are sessions specific to PTP messaging and are covered in detail in Chapter 4.

The interface javax.jms.Queue defines two methods. The first one returns the name of the queue:

     public java.lang.String getQueueName() throws JMSException 

This method throws a JMSException if the provider fails to return the queue name due to any internal server error.

The second method returns a formatted and printable version of the queue name. This is actually the toString() method defined in the implementation class that overrides the same defined in java.lang.Object:

     public java.lang.String toString() 

Temporary Queues

Unlike normal queues that are created for permanent use, temporary queues are dynamic queues that are created only for the lifetime of a queue connection.

Temporary queues can be used for specifying the destination on which a response is expected in a request/response paradigm using PTP messaging. The response destination can be specified using the JMSReplyTo message header when a message is sent. Message headers are explained in detail in the next chapter. Temporary queues that are created using queue sessions can be accessed only by the session that created the queue and all the other sessions belonging to the same connection.

Temporary queues are defined by the JMS interface javax.jms.TemporaryQueue that extends the interface javax.jms.Queue.

The interface javax.jms.TemporaryQueue defines only one method that is used for deleting the temporary queue:

     public void delete() throws JMSException 

This method will throw a JMSException if the queue is still in use by senders or receivers.

Topics

Topics are specialized Destination objects used in Pub/Sub messaging. Each message sent to a topic can be shared between different subscribers. Topics are defined in JMS using the interface javax.jms.Topic. JMS providers provide implementation classes for this interface, which can be created, configured, and stored in a namespace by the JMS administrator and can be looked up later by JMS clients. Topics can also be created using topic sessions. Topic sessions are sessions specific to Pub/Sub messaging and are covered in detail in Chapter 5.

The interface javax.jms.Topic defines two methods. The first one returns the name of the topic:

     public java.lang.String getTopicName() throws JMSException 

This method throws and a trappable JMSException if the provider fails to return the topic name due to any internal server error.

The second method returns a formatted and printable version of the topic name. This is actually the toString() method defined in the implementation class that overrides the same defined in java.lang.Object:

     public java.lang.String toString() 

Temporary Topics

Unlike normal topics that are created for permanent use, temporary topics are dynamic topics that are created only for the life of a topic connection.

Temporary topics can be used for specifying the destination on which a response is expected in a request/response paradigm using Pub/Sub messaging. The response destination can be specified using the JMSReplyTo message header when a message is sent. Temporary topics that are created using topic sessions can be accessed only by the session that created the topic and all the other sessions belonging to the same connection.

Temporary topics are defined by the JMS interface javax.jms.TemporaryTopic, which extends the interface javax.jms.Topic.

The interface javax.jms.TemporaryTopic defines only one method that is used for deleting the temporary topic:

     public void delete() throws JMSException 

This method will throw a trappable JMSException if the queue is still in use by publishers or subscribers.

Class Hierarchy

The class hierarchy for JMS destinations is depicted in the class diagram shown below:

click to expand

JMS Client to Look up Administered Objects

Now we will write a simple JMS client that will look up connection factories and destinations from a namespace and create a connection to the JMS provider. The client will work with any JMS-compliant provider and has been tested with JMQ 1.1 (Java Message Queue) from Sun Microsystems. JMQ is freely available for development and can be downloaded from http://java.sun.com.

One important step involved in building JMS applications is creating and configuring administered objects. Most of the messaging product vendors provide custom tools for accomplishing this task. In the sample application, we will create and store a queue connection factory, a queue, a topic connection factory, and a topic in the standard Windows NT file system namespace. We will then use JNDI to lookup these objects.

Note 

The listing below shows the batch file used for creating, configuring, and storing the required Administered objects for the sample application. Note that all the code in this chapter can be downloaded from the Wrox website at http://www.wrox.com.

The batch file creates a queue called myQueue, a topic called myTopic, a queue connection factory called QCFactory, and a topic connection factory called TCFactory. These objects are stored under the C : \temp directory and are available for standard JNDI lookup using the file system context service provider.

The configuration information for the connection factories specifies that the message provider will be run on localhost and listen on the default port. The -t option is used to specify the type of the Administered object. The -i option specifies the initial context factory. For a complete list of options please refer to the JMQ documentation provided with the installation:

     @echo off     if "%JMQ_HOME%\lib\jmq.jar" == "\lib\jmq.jar" goto nojmqhome     REM Create and add the queue     call "%JMQ_HOME%\bin\jmqconfig" -a -t q -n myQueue -o "name=myQueue" -i     "com.sun.jndi.fscontext.RefFSContextFactory" -u "file:C:\temp"     REM Create and add the topic     call "%JMQ_HOME%\bin\jmqconfig" -a -t t -n myTopic -o "name=myTopic" -i     "com.sun.jndi.fscontext.RefFSContextFactory" -u "file:C:\temp"     REM Create and add the queue connection factory     call "%JMQ_HOME%\bin\jmqconfig" -a -t qf -n QCFactory -o "host=localhost"     -i "com.sun.jndi.fscontext.RefFSContextFactory" -u "file:C:\temp"     REM Create and add the topic connection factory     call "%JMQ_HOME%\bin\jmqconfig" -a -t tf -n TCFactory -o "host=localhost"     -i "com.sun.jndi.fscontext.RefFSContextFactory" -u "file:C:\temp"     goto end     :nojmqhome        echo Please set the JMQ_HOME environment variable.        goto end     :end 

Running the above batch file would produce the following output in the command window:

click to expand

The listing below shows a JMS client using JNDI lookup to retrieve the Administered objects created and stored using the above batch file:

     import javax.naming.NamingException;     import javax.naming.Context;     import javax.naming.InitialContext;     import java.util.Properties;     import javax.jms.Queue;     import javax.jms.QueueConnectionFactory;     import javax.jms.QueueConnection;     import javax.jms.Topic;     import javax.jms.TopicConnectionFactory;     import javax.jms.TopicConnection;     import javax.jms.JMSException; 

The JMSLookup class creates the JNDI initial context using the file system initial context factory:

     public class JMSLookup {        //Initial context factory        public static final String CTX_FACT =                    "com.sun.jndi.fscontext.RefFSContextFactory";        //Provider URL        public static final String PROV_URL = "file:C:\\temp";        //JNDI name for the queue connection factory        public static final String QCF_NAME = "QCFactory";        //JNDI name for the topic connection factory        public static final String TCF_NAME = "TCFactory";        //JNDI name for the queue        public static final String QUEUE_NAME = "myQueue";        //JNDI name for the topic        public static final String TOPIC_NAME = "myTopic";        public static void main(String args []) throws Exception {           //Properties for storing JNDI configuration info           Properties prop = new Properties();           //Add the initial context factory           prop. put (Context. INITIAL_CONTEXT_FACTORY, CTX_FACT);           //Add the provider URL           prop.put(Context.PROVIDER_URL, PROV_URL);           //Create the initial context           Context ctx = new InitialContext(prop); 

Instead of passing the JNDI environment properties using Properties objects, they can also be passed as system properties using the -D option when the JVM is invoked. The initial context is then used for looking up the Administered objects stored in the file system namespace:

           System.out.println("\nRetrieving: Queue connection factory.");           QueueConnectionFactory qcf =              (QueueConnectionFactory)ctx.lookup(QCF_NAME);           System.out.println("Retrieved: Queue connection factory.");           System.out.println("Obtaining: Queue connection.");           QueueConnection qConn = qcf.createQueueConnection();           System.out.println("Obtained: Queue connection.");           System.out.println("Retrieving: Topic connection factory.");           TopicConnectionFactory tcf =              (TopicConnectionFactory)ctx.lookup(TCF_NAME) ;           System.out.println("Retrieved: Topic connection factory.");           System.out.println("Obtaining: Topic connection.");           TopicConnection tConn = tcf.createTopicConnection();           System.out.println("Obtained: Topic connection.");           System.out.println("Retrieving: Queue.");           Queue queue = (Queue)ctx. lookup (QUEUE_NAME);           System.out.println(queue);           System.out.println("Retrieved: Queue.");           System.out.println("Retrieving: Topic.");           Topic topic = (Topic)ctx.lookup(TOPIC_NAME);           System.out.println(topic);           System.out.println("Retrieved: Topic.");           System.exit (0);        }    } 

When you compile and run the example please make sure you have the required JAR files from the JMQ lib directory in the classpath. These are fscontext. jar, jms. jar, jndi. jar, jmq. jar, and providerutil.jar.

Start the JMQ router by executing the irouter binary. Invoke the Java interpreter on JMSLookup with all the required class files in the classpath. The output is shown below:

click to expand



Professional JMS
Professional JMS
ISBN: 1861004931
EAN: 2147483647
Year: 2000
Pages: 154

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net