|Skip Navigation Links|
|Exit Print View|
|Oracle GlassFish Server Message Queue 4.5 Developer's Guide for Java Clients|
All messaging occurs within the context of a connection. Connections are created using a connection factory encapsulating all of the needed configuration properties for connecting to a particular JMS provider. A connection’s configuration properties are completely determined by the connection factory, and cannot be changed once the connection has been created. Thus the only way to control the properties of a connection is by setting those of the connection factory you use to create it.
Typically, a connection factory is created for you by a Message Queue administrator and preconfigured, using the administration tools described in the Chapter 1, Administrative Tasks and Tools, in Oracle GlassFish Server Message Queue 4.5 Administration Guidewith whatever property settings are appropriate for connecting to particular JMS provider. The factory is then placed in a publicly available administered object store, where you can access it by name using the Java Naming and Directory Interface (JNDI) API. This arrangement has several benefits:
It allows the administrator to control the properties of client connections to the provider, ensuring that they are properly configured.
It enables the administrator to tune performance and improve throughput by adjusting configuration settings even after an application has been deployed.
By relying on the predefined connection factory to handle the configuration details, it helps keep client code provider-independent and thus more easily portable from one JMS provider to another.
Sometimes, however, it may be more convenient to dispense with JNDI lookup and simply create your own connection factory by direct instantiation. Although hard-coding configuration values for a particular JMS provider directly into your application code sacrifices flexibility and provider-independence, this approach might make sense in some circumstances: for example, in the early stages of application development and debugging, or in applications where reconfigurability and portability to other providers are not important concerns.
The following sections describe these two approaches to obtaining a connection factory: by JNDI lookup or direct instantiation.
Example 2-1 shows how to look up a connection factory object in the JNDI object store. The code example is explained in the procedure that follows.
Note - If a Message Queue client is a J2EE component, JNDI resources are provided by the J2EE container. In such cases, JNDI lookup code may differ from that shown here; see your J2EE provider documentation for details.
Example 2-1 Looking Up a Connection Factory
// Create the environment for constructing the initial JNDI // naming context. Hashtable env = new Hashtable(); // Store the environment attributes that tell JNDI which initial context // factory to use and where to find the provider.// env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory"); env.put(Context.PROVIDER_URL, "file:///C:/imq_admin_objects"); // Create the initial context. Context ctx = new InitialContext(env); // Look up the connection factory object in the JNDI object store. String CF_LOOKUP_NAME = "MyConnectionFactory"; ConnectionFactory myFactory = (ConnectionFactory) ctx.lookup (CF_LOOKUP_NAME);
How you create the initial context depends on whether you are using a file-system object store or a Lightweight Directory Access Protocol (LDAP) server for your Message Queue administered objects. The code shown here assumes a file-system store; for information about the corresponding LDAP object store attributes, see Using an LDAP User Repository in Oracle GlassFish Server Message Queue 4.5 Administration Guide
Hashtable env = new Hashtable();
You can also set an environment by specifying system properties on the command line, rather than programmatically. For instructions, see the README file in the JMS example applications directory.
The names of these attributes are defined as static constants in class Context:
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory"); env.put(Context.PROVIDER_URL, "file:///C:/imq_admin_objects");
Note - The directory represented by C:/imq_admin_objects must already exist; if necessary, you must create the directory before referencing it in your code.
Context ctx = new InitialContext(env);
If you use system properties to set the environment, omit the environment parameter when creating the context:
Context ctx = new InitialContext();
String CF_LOOKUP_NAME = "MyConnectionFactory"; ConnectionFactory myFactory = (ConnectionFactory) ctx.lookup(CF_LOOKUP_NAME);
The lookup name you use, CF_LOOKUP_NAME, must match the name used when the object was stored.
You can now proceed to use the connection factory to create connections to the message broker, as described under Using Connections.
It is recommended that you use a connection factory just as you receive it from a JNDI lookup, with the property settings originally configured by your Message Queue administrator. However, there may be times when you need to override the preconfigured properties with different values of your own. You can do this from within your application code by calling the connection factory’s setProperty method. This method (inherited from the superclass AdministeredObject) takes two string arguments giving the name and value of the property to be set. The property names for the first argument are defined as static constants in the Message Queue class ConnectionConfiguration: for instance, the statement
sets the default password for establishing broker connections. See Connection Factory Attributes in Oracle GlassFish Server Message Queue 4.5 Administration Guidefor complete information on the available connection factory configuration attributes.
java -DimqDefaultPassword=mellon MyMQClient
starts an application named MyMQClient with the same default password as in the preceding example. Setting a property value this way overrides any other value specified for it, whether preconfigured in the JNDI object store or set programmatically with the setProperty method.
Note - A Message Queue administrator can prevent a connection factory’s properties from being overridden by specifying that the object be read-only when placing it in the object store. The properties of such a factory cannot be changed in any way, whether with the -D option from the command line or using the setProperty method from within your client application’s code. Any attempt to override the factory’s property values will simply be ignored.
Example 2-2 shows how to create a connection factory object by direct instantiation and configure its properties.
Example 2-2 Instantiating a Connection Factory
// Instantiate the connection factory object. com.sun.messaging.ConnectionFactory myFactory = new com.sun.messaging.ConnectionFactory(); // Set the connection factory’s configuration properties. myFactory.setProperty(ConnectionConfiguration.imqAddressList, "localhost:7676,broker2:5000,broker3:9999");
The following procedure explains each program satement in the previous code sample.
The name ConnectionFactory is defined both as a JMS interface (in package javax.jms) and as a Message Queue class (in com.sun.messaging) that implements that interface. Since only a class can be instantiated, you must use the constructor defined in com.sun.messaging to create your connection factory object. Note, however, that you cannot import the name from both packages without causing a compilation error. Hence, if you have imported the entire package javax.jms.*, you must qualify the constructor with the full package name when instantiating the object:
com.sun.messaging.ConnectionFactory myFactory = new com.sun.messaging.ConnectionFactory();
Notice that the type declaration for the variable myFactory, to which the instantiated connection factory is assigned, is also qualified with the full package name. This is because the setProperty method, used in Instantiating a Connection Factory, belongs to the ConnectionFactory class defined in the package com.sun.messaging, rather than to the ConnectionFactory interface defined in javax.jms . Thus in order for the compiler to recognize this method, myFactory must be typed explicitly as com.sun.messaging.ConnectionFactory rather than simply ConnectionFactory (which would resolve to javax.jms.ConnectionFactory after importing javax.jms.* ).
The most important configuration property is imqAddressList, which specifies the host names and port numbers of the message brokers to which the factory creates connections. By default, the factory returned by the ConnectionFactory constructor in Instantiating a Connection Factory is configured to create connections to a broker on host localhost at port number 7676. If necessary, you can use the setProperty method, described in the preceding section, to change that setting:
When specifying the host name portion of a broker, you can use a literal IPv4 or IPv6 address instead of a host name. If you use a literal IPv6 address, its format must conform to RFC2732, Format for Literal IPv6 Addresses in URL's.
Of course, you can also set any other configuration properties your application may require. See Connection Factory Attributes in Oracle GlassFish Server Message Queue 4.5 Administration Guide for a list of the available connection factory attributes.
You can now proceed to use the connection factory to create connections to the message service, as described in the next section.
Connection myConnection = myFactory.createConnection("mithrandir", "mellon");
Before granting the connection, Message Queue authenticates the user name and password by looking them up in its user repository. As a convenience for developers who do not wish to go to the trouble of populating a user repository during application development and testing, there is also a parameterless form of the createConnection method:
Connection myConnection = myFactory.createConnection();
This unified-domain createConnection method is part of the generic JMS ConnectionFactory interface, defined in package javax.jms; the Message Queue version in com.sun.messaging adds corresponding methods createQueueConnection and createTopicConnection for use specifically with the point-to-point and publish/subscribe domains.
Table 2-2 Connection Methods
The first argument to createSession is a boolean indicating whether the session is transacted; the second specifies its acknowledgment mode. Possible values for this second argument are AUTO_ACKNOWLEDGE, CLIENT_ACKNOWLEDGE, and DUPS_OK_ACKNOWLEDGE, all defined as static constants in the standard JMS Session interface, javax.jms.Session ; the extended Message Queue version of the interface, com.sun.messaging.jms.Session , adds another such constant, NO_ACKNOWLEDGE. See Acknowledgment Modes and Transacted Sessions for further discussion.
If your client application will be using the publish/subscribe domain to create durable topic subscriptions, it must have a client identifier to identify itself to the message service. In general, the most convenient arrangement is to configure the client runtime to provide a unique client identifier automatically for each client. However, the Connection interface also provides a method, setClientID, for setting a client identifier explicitly, and a corresponding getClientID method for retrieving its value. See Assigning Client Identifiers and Client Identifier in Oracle GlassFish Server Message Queue 4.5 Administration Guide for more information.
You should also use the setExceptionListener method to register an exception listener for the connection. This is an object implementing the JMS ExceptionListener interface, which consists of the single method onException:
void onException (JMSException exception)
In the event of a problem with the connection, the message broker will call this method, passing an exception object identifying the nature of the problem.
A connection’s getMetaData method returns a ConnectionMetaData object, which in turn provides methods for obtaining various items of information about the connection, such as its JMS version and the name and version of the JMS provider.
The createConnectionConsumer and createDurableConnectionConsumer methods (as well as the session methods setMessageListener and getMessageListener, listed in Table 2-3) are used for concurrent message consumption; see the Java Message Service Specification for more information.
It is important not to do this until after you have created any message consumers you will be using to receive messages on the connection. Starting the connection before creating the consumers risks missing some incoming messages before the consumers are ready to receive them. It is not necessary to start the connection in order to send outgoing messages.
This automatically closes all sessions, message producers, and message consumers associated with the connection and deletes any temporary destinations. All pending message receives are terminated and any transactions in progress are rolled back. Closing a connection does not force an acknowledgment of client-acknowledged sessions.
A connection service that is based on the Transport Layer Security (TLS/SSL) standard is used to authenticate and encrypt messages sent between the client and the broker. This section describes what the client needs to do to use TLS/SSL connections. A user can also establish a secure connection by way of an HTTPS tunnel servlet. For information on setting up secure connections over HTTP, see Appendix C, HTTP/HTTPS Support, in Oracle GlassFish Server Message Queue 4.5 Administration Guide.
Some of the work needed to set up a TLS/SSL connection is done by an administrator. This section summarizes these steps. For complete information about the administrative work required, please see Message Encryption in Oracle GlassFish Server Message Queue 4.5 Administration Guide.
To set up a secure connection service, you must do the following.
Generate a self-signed or signed certificate for the broker (administrator).
Enable the ssljms connection service in the broker (administrator).
Start the broker (administrator).
Configure and run the client as explained below.
To configure a client to use a TLS/SSL connection you must do the following.
If your client is not using J2SDK 1.4 (which has JSSE and JNDI support built in), make sure the client has the following files in its class path: jsse.jar, jnet.jar, jcert, jar, jndi.jar.
Make sure the client has the following Message Queue files in its class path: imq.jar, jms.jar.
If the client is not willing to trust the broker's self-signed certificate, set the imqSSLIsHostTrusted attribute to false for the connection factory from which you get the TLS/SSL connection.
Connect to the broker's ssljms service. There are two ways to do this. The first is to specify the service name ssljms in the address for the broker when you provide a value for the imqAddressList attribute of the connection factory from which you obtain the connection. When you run the client, it will be connected to the broker by a TLS/SSLconnection. The second is to specify the following directive when you run the command that starts the client.
java -DimqConnectionType=TLS clientAppName