Resolution: Won't Fix
Affects Version/s: 1.1
Fix Version/s: None
This is a proposal to extend the JMS specification to define a standard way of instantiating and configuring connection factory objects.
A connection factory is an example of an administered object. The JMS 1.1 specification establishes the convention whereby administered objects (connection factories and destinations) are not created in application code. Instead they are created by an administrator using tools specific to the JMS provider and stored in JNDI. The application code then looks up the connection factory or destination from JNDI and uses them in accordance with the JMS API.
The purpose of this is clearly stated in the specification: it is to allow everything that is non-standard and specific to a particular JMS provider to be kept out of the code itself. (See Relevant sections of the JMS 1.1 Specification below).
In the case of connection factories, this means that the application doesn't have to contain any information about how to connect to the JMS provider. For example, if the JMS provider is running on some remote server, the application doesn't contain any information about the location of the server or the protocol used to connect to it. All this information is defined when the connection factory is created by an administrator, separate from the application itself.
However the JMS specification says nothing about how the connection factory itself is created or configured, other than saying that it is done by "provider-specific facilities". All it says is that:
- it must implement javax.jms.ConnectionFactory,
- it must implement javax.naming.Referenceable and java.io.Serializable, so it can be stored in all JNDI naming contexts (section 4.2)
- it is recommended that implementations "follow the JavaBeans design patterns"
- it allows client identifier to be set (section 4.3.2)
However the specification does not define:
- how a connection factory is instantiated
- how the location of the server is defined
- how client identifier is set
- how other properties are set
Now although this omission from the JMS 1.1 specification is no doubt deliberate, it does cause some difficulties:
- it is not possible to develop standard tools for creating connection factories (and binding them in JNDI) which work with multiple JMS providers
- in a Java EE environment, there is no standard way of configuring the JMS requirements of a particular application
- it is inconsistent with way in which a JDBC DataSource objects is defined, both in a Java SE and a Java EE environment. This is discussed more in How JDBC DataSource objects are configured.
It is proposed that the way that a ConnectionFactory is created and configured be partially standardised in a manner similar to JDBC DataSource objects, as follows:
- A ConnectionFactory implementation is a JavaBean, and may be instantiated by executing the no-arg constructor of its implementation class. For example:
- The JMS specification will define a set of properties which may be used to identify and describe a ConnectionFactory implementation.
|description||String||description of this connection factory|
|user||String||user name (may be overridden when createConnection is called)|
|password||String||password corresponding to user name may be overridden when createConnection is called)|
|networkProtocol||String||network protocol used to communicate with the JMS provider|
|serverName||String||server name of the JMS provider|
|portNumber||String||port number of the JMS provider|
|networkProtocols||String||array of network protocols used to communicate with the JMS provider|
|serverNames||String||array of server names of the JMS provider|
|portNumbers||String||array of port numbers of the JMS provider|
|url||String||Opaque string which defines how to connect to the JMS provider|
|clientId||String||JMS client identifier|
- ConnectionFactory properties follow the convention specified for properties of JavaBeans components in the JavaBeans 1.01 Specification. ConnectionFactory implementations may augment this set with implementation-specific properties. If new properties are added, they must be given names that do not conflict with the
standard property names.
- ConnectionFactory implementations must provide "getter" and "setter" methods for each property they support. These properties typically are intended to be initialized before the object is bound in JNDI for subsequent use by an application.
- ConnectionFactory properties are not intended to be directly accessible by JMS clients. This design is reinforced by defining the access methods on the implementation class rather than on the public DataSource interface used by applications. Furthermore, the object that the client manipulates can be a wrapper that only
implements the ConnectionFactory interface. The setter and getter methods for the properties need not be exposed to the client.
- Management tools that need to manipulate the properties of a ConnectionFactory implementation can access those properties using introspection.
Note that this gives three alternative ways to define how the connection factory should communicate with the server:
- an opaque URL string
- a tuple of (networkProtocol, serverName, portNumber), where networkProtocol may be omitted
- an array of such tuples, represented here as three separate arrays
A JMS provider may support all, some or none of these alternatives.
- If both URL and one of the other forms are supported and both are supplied, the URL is used.
- If the single tuple (networkProtocol, serverName, portNumber) is supported, then a single-element array of tuples will also be supported
(Much of the wording above is based on section 9.4.1 DataSource properties of the JDBC 4.0 specification.)
Please also see the following additional information which has been added as separate notes below:
- How JDBC DataSource objects are configured
- Relevant sections of the JMS 1.1 Specification