Sun Java System Message Queue 3.5 SP1 Java Client Developer's Guide |
Chapter 3
Using Administered ObjectsAdministered objects encapsulate provider-specific implementation and configuration information in objects that are used by Message Queue clients.
Message Queue provides two types of JMS administered objects—connection factory and destination—as well as a JAXM administered object. While all encapsulate provider-specific information, they have very different uses.
ConnectionFactory and XAConnectionFactory (distributed transaction) objects are used to create connections to the Message Queue server. Destination objects (which represent physical destinations) are used to create JMS message consumers and producers (see Developing a Simple Client Application). The JAXM endpoint administered object is used to send SOAP messages (see Chapter 6, "Working With SOAP Messages").
There are two approaches to the use of administered objects:
- They can be created and configured by an administrator, stored in an object store, accessed by clients through standard JNDI lookup code, and then used in a provider-independent manner.
- They can be instantiated and configured by a developer when writing application code. In this case, they are used in a provider-specific manner.
The approach you take in using administered objects depends on the environment in which your application will be run and how much control you want your client to have over Message Queue-specific configuration details. This chapter describes these two approaches and explains how to code your client for each.
JNDI Lookup of Administered ObjectsIf you wish an application to be run under controlled conditions in a centrally administered messaging environment, then Message Queue administered objects should be created and configured by an administrator. This makes it possible for the administrator to do the following:
- control the behavior of connections by requiring clients to access pre-configured ConnectionFactory (and XAConnectionFactory) objects through a JNDI lookup.
- control the proliferation of physical destinations by requiring clients to access only Destination objects that correspond to existing physical destinations.
This approach gives the administrator control over message server and client runtime configuration details, and at the same time allows clients to be JMS provider-independent: they do not have to know about provider-specific syntax and object naming conventions or provider-specific configuration properties.
An administrator creates administered objects in an object store using Message Queue administration tools, as described in the Message Queue Administration Guide. When creating an administered object, the administrator can specify that it be read only—that is, clients cannot change Message Queue-specific configuration values specified when the object was created. In other words, application code cannot set attribute values on read-only administered objects, nor can they be overridden using client startup options, as described in Starting Client Applications With Overrides.
While it is possible for clients to instantiate ConnectionFactory (and XAConnectionFactory) and destination administered objects on their own, this practice undermines the basic purpose of an administered object—to allow an administrator to control the broker resources required by an application and to tune application performance. Instantiating administered objects also makes a client provider specific.
Looking Up ConnectionFactory Objects
To Perform a JNDI Lookup of a ConnectionFactory Object
- Create an initial context for the JNDI lookup.
The details of how you create this context depend on whether you are using a file-system object store or an LDAP server for your Message Queue administered objects. The code below assumes a file-system store. For information about the corresponding LDAP object store attributes, see the Message Queue Administration Guide.
Hashtable env = new Hashtable();
env.put (Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.fscontext.RefFSContextFactory");
env.put (Context.PROVIDER_URL,
"file:///c:/imq_admin_objects");
Context ctx = new InitialContext(env);
Note
You need to create the directory represented by c:/imq_admin_objects before referencing it in your code. (that is, c:/imq_admin_objects must be an existing directory).
You can also set an environment by specifying system properties on the command line, rather than programmatically, as shown above. For instructions, see the README file in the JMS example applications directory.
If you use system properties to set the environment, then you initialize the context without providing the env parameter:
Context ctx = new InitialContext();
- Perform a JNDI lookup on the “lookup” name under which the ConnectionFactory or XAConnectionFactory object was stored in the JNDI object store.
QueueConnectionFactory myQConnFactory = (QueueConnectionFactory)
ctx.lookup(“MyQueueConnectionFactory”);It is recommended that you use this connection factory as originally configured. For a discussion of ConnectionFactory and XAConnectionFactory object attributes, see Client Runtime Configurable Properties and for a complete list of attributes, see ConnectionFactory Administered Object.
- Use the ConnectionFactory to create a connection object.
QueueConnection myQConn =
myQConnFactory.createQueueConnection();The code in the previous steps is shown in Code Example 3-1. (The directory represented by c:/imq_admin_objects must be an existing directory.)
The code in the previous steps is shown in Code Example 3-1.
Looking Up Destination Objects
To Perform a JNDI Lookup of a Destination Object
Instantiating Administered ObjectsIf you do not wish an application to be run under controlled conditions in a centrally administered environment, then you can instantiate and configure administered objects in application code.
While this approach gives you, the developer, control over message server and client runtime configuration details, it also means that your clients are not supported by other JMS providers. Typically, you might instantiate administered objects in application code in the following situations:
Instantiating administered objects in application code means you are hard-coding configuration values into your application. You give up the flexibility of having an administrator reconfigure the administered objects to achieve higher performance or throughput after an application has been deployed.
Instantiating ConnectionFactory Objects
There are two object constructors for instantiating Message Queue ConnectionFactory administered objects, one for each programming domain:
- Publish/subscribe (Topic) domain
new com.sun.messaging.TopicConnectionFactory();
Instantiates a TopicConnectionFactory with a default configuration (creates Topic TCP-based connections to a broker running on “localhost” at port number 7676).
- Point to point (Queue) domain
new com.sun.messaging.QueueConnectionFactory();
Instantiates a QueueConnectionFactory with a default configuration (creates Queue TCP-based connections to a broker running on “localhost” at port number 7676).
To Directly Instantiate and Configure a ConnectionFactory Object
- Instantiate a Topic or Queue ConnectionFactory object using the appropriate constructor.
com.sun.messaging.QueueConnectionFactory myQConnFactory =
new com.sun.messaging.QueueConnectionFactory();- Configure the ConnectionFactory object.
myQConnFactory.setProperty("imqBrokerHostName", "new_hostname");
myQConnFactory.setProperty("imqBrokerHostPort", "7878");For a discussion of ConnectionFactory configuration properties, see Client Runtime Configurable Properties and for a complete list of properties, see ConnectionFactory Administered Object.
- Use the ConnectionFactory to create a Connection object.
QueueConnection myQConn =
myQConnFactory.createQueueConnection();The code in the previous steps is shown in Code Example 3-2.
Code Example 3-2 Instantiating a ConnectionFactory Object
com.sun.messaging.QueueConnectionFactory myQConnFactory =
new com.sun.messaging.QueueConnectionFactory();try {
myQConnFactory.setProperty("imqBrokerHostName", "new_host");
myQConnFactory.setProperty("imqBrokerHostPort", "7878");
} catch (JMSException je) {
}
QueueConnection myQConn =
myQConnFactory.createQueueConnection();
Instantiating Destination Objects
There are two object constructors for instantiating Message Queue Destination administered objects, one for each programming domain:
- Publish/subscribe (Topic) domain
new com.sun.messaging.Topic();
Instantiates a Topic with the default destination name of “Untitled_Destination_Object”.
- Point to point (Queue) domain
new com.sun.messaging.Queue();
Instantiates a Queue with the default destination name of “Untitled_Destination_Object”.
To Directly Instantiate and Configure a Destination Object
- Instantiate a Topic or Queue Destination object using the appropriate constructor.
com.sun.messaging.Queue myQueue = new com.sun.messaging.Queue();
- Configure the Destination object.
myQueue.setProperty("imqDestinationName", "new_queue_name");
- After creating a session, you use the Destination object to create a MessageProducer or MessageConsumer object.
QueueSender qs = qSession.createSender((Queue)myQueue);
The code is shown in Code Example 3-3.
Code Example 3-3 Instantiating a Destination Object
com.sun.messaging.Queue myQueue = new com.sun.messaging.Queue();
try {
myQueue.setProperty("imqDestinationName", "new_queue_name");
} catch (JMSException je) {
}
...
QueueSender qs = qSession.createSender((Queue)myQueue);
...
Starting Client Applications With OverridesAs with any Java application, you can start messaging applications using the command-line to specify system properties. This mechanism can also be used to override attribute values of Message Queue administered objects used in application code. You can override the configuration of Message Queue administered objects that are accessed through a JNDI lookup and Message Queue administered objects that are instantiated and configured using setProperty() methods in application code.
To override administered object settings, use the following command line syntax:
java [[-Dattribute=value ]...] clientAppName
where attribute corresponds to any of the ConnectionFactory administered object attributes documented in Client Runtime Configurable Properties.
For example, if you want a client to connect to a different broker than that specified in a ConnectionFactory administered object accessed in the application code, you can start up the client using command line overrides to set the imqBrokerHostName and imqBrokerHostPort of another broker.
It is also possible to set system properties within application code using the System.setProperty() method. This method will override attribute values of Message Queue administered objects in the same way that command line options do.
If an administered object has been set as read-only, however, the values of its attributes cannot be changed using either command-line overrides or the System.setProperty() method. Any such overrides will simply be ignored.