jsr343-experts@jms-spec.java.net

[jsr343-experts] Re: (JMS_SPEC-46) Define standard API to create and configure a ConnectionFactory

From: John D. Ament <john.d.ament_at_gmail.com>
Date: Fri, 16 Sep 2011 14:53:54 -0400

Nigel,

I like the idea, but am not sure how it could be implemented. Maybe....

ConnectionFactory cf =
javax.jms.spi.ConnectionFactoryLocator.getInstance("activemq://host,host,host:port;port;port/?factory=JmsXA");

Maybe via service loaders? In general I love the idea and helps make the DI
proposal a bit easier in the SE environment as well.

John

On Fri, Sep 16, 2011 at 11:32 AM, Nigel Deakin <nigel.deakin_at_oracle.com>wrote:

> A month ago I made this proposal:
>
>
> On 11/08/2011 16:46, Nigel Deakin wrote:
>
>> I have created this JIRA issue
>> http://java.net/jira/browse/**JMS_SPEC-46<http://java.net/jira/browse/JMS_SPEC-46>
>>
>> Aspects of this issue were raised by both Clebert and Emran, but I believe
>> there is a wider requirement which comes out
>> of the Java EE platform initiatative to allow JMS and other resources to
>> be specified in more detail.
>>
>> Clebert wrote: "[I would like to see the ability] to instantiate
>> connection factories directly. I would make a relation
>> to JDBC here. You can make here an analogy to JDBC as you don't need JNDI
>> to make an initial connection."
>>
>> Emran wrote: "[I would like to see] API on connection factories to create
>> connections with secure transport (I have seen
>> this feature in the jms containers as a configurable property on
>> connection factories)."
>>
>> This is quite a long description and it may be easier to read the
>> formatted version in the JIRA issue rather than the
>> text version below. In any case, I would appreciate your comments on what
>> is a small but potentially very significant
>> change.
>>
>
> In response I got just one comment, from Reza, who wrote: "This seems like
> an excellent, timely change.". There were no other comments. Since this is
> potentially quite a significant change, at least for vendors, I'd like to
> invite some more specific comments rather than simply declare that it
> approved by default.
>
> In particular, I'd like to invite Clebert and Emran, who raised this issue
> originally, whether this satisfies their requirements. It would also be good
> to hear from the other representatives of JMS vendors on this EG...
>
> Nigel
>
>
>
> Nigel
>>
>>
>> This is a proposal to extend the JMS specification to define a standard
>> way of instantiating and configuring connection
>> factory objects.
>>
>> Background
>> ----------
>>
>> 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'.
>>
>> Proposals
>> ---------
>>
>> 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:
>>
>> ConnectionFactory cf = Class.forName("com.sun.**
>> messaging.ConnectionFactory")
>>
>> * The JMS specification will define a set of properties which may be used
>> to identify and describe a ConnectionFactory
>> implementation.
>>
>> || Property name || Type || Description||
>> | 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.)
>>
>> How JDBC DataSource objects are configured
>> ------------------------------**------------
>>
>> This section describes how, although JDBC DataSource objects are similar
>> in concept to JMS ConnectionFactory objects,
>> the JDBC and Java EE specifications define in much more detail how
>> DataSource objects are created and configured than
>> the JMS specification defines for ConnectionFactory objects.
>>
>> A JMS ConnectionFactory is a factory for creating connections to a JMS
>> provider, using the createConnection method. In
>> JDBC, a javax.jdbc.DataSource fulfils a similar role as a factory for
>> creating connections to a JDBC database, using the
>> getConnection method.
>>
>> Section 9.4.2 recommends that javax.jdbc.DataSource objects are stored in
>> JNDI to allow database-specific configuration
>> to be kept separate from the application. This much is similar to JMS.
>>
>> However the JNDI specification differs from JMS in providing a lot of
>> guidance on how to create a DataSource. Section
>> 9.4.1 contains a whole list of standard data source properties which may
>> be supported:
>>
>> * databaseName
>> * dataSourceName
>> * description
>> * networkProtocol
>> * password
>> * portNumber
>> * roleName
>> * serverName
>> * user
>>
>> Although the specification suggests that not all DataSource
>> implementations support all properties, it does define names
>> for these most common properties, and specifies that when supported, they
>> must be configurable using standard JavaBeans
>> "setters and getters".
>>
>> In addition, a DataSource may be instantiated by invoking its no-arg
>> constructor. This isn't stated explicitly in the
>> spec (if the DataSource were a JavaBean then a no-arg constructor would be
>> mandatory, but the spec only states that its
>> properties follow the conventions specified for properties of JavaBeans,
>> not that a DataSource is itself a JavaBean) but
>> in practice the convention that it can is well-established.
>>
>> This means that a DataSource may be instantiated, given the name of the
>> implementation class as a String, using code of
>> the following form:
>>
>> DataSource ds = Class.forName("oracle.jdbc.**pool.OracleDataSource")
>>
>> Meanwhile, the Java EE 6 specification defines a DataSourceDefinition
>> annotation and a corresponding <data-source>
>> element which defines the following properties of a DataSource:
>>
>> * className (required)
>> * name (required)
>> * databaseName
>> * description
>> * initialPoolSize
>> * isolationLevel
>> * loginTimeout
>> * maxIdleTime
>> * maxPoolSize
>> * maxStatements
>> * minPoolSize
>> * password
>> * portNumber
>> * properties
>> * serverName
>> * transactional
>> * url
>> * user
>>
>> This is a longer list than is defined in JDBC, partly because the JDBC
>> spec is older, but also because it also includes
>> pooling properties. Perhaps of the most interest is the url property,
>> which may be provided as an alternative to
>> serverName and port.
>>
>> Relevant sections of the JMS 1.1 Specification
>> ------------------------------**----------------
>>
>> The relevant sections of the JMS specification are given below:
>>
>> Section 2.3 'Administration'
>>
>> "It is expected that JMS providers will differ significantly in their
>> underlying messaging technology. It is also
>> expected there will be major differences in how a provider’s system is
>> installed and administered.
>>
>> "If JMS clients are to be portable, they must be isolated from these
>> proprietary aspects of a provider. This is done by
>> defining JMS administered objects that are created and customized by a
>> provider's administrator and later used by
>> clients. The client uses them through JMS interfaces that are portable.
>> The administrator creates them using
>> provider-specific facilities.
>>
>> "There are two types of JMS administered objects:
>>
>> • "ConnectionFactory - This is the object a client uses to create a
>> connection with a provider.
>> • "Destination - This is the object a client uses to specify the
>> destination of messages it is sending and the source of
>> messages it receives.
>>
>> "Administered objects are placed in a JNDI namespace by an administrator.
>> A JMS client typically notes in its
>> documentation the JMS administered objects it requires and how the JNDI
>> names of these objects should be provided to it.
>>
>> Section 4.2 'Administered Objects'
>>
>> "JMS administered objects are objects containing JMS configuration
>> information that are created by a JMS administrator
>> and later used by JMS clients. They make it practical to administer JMS
>> applications in the enterprise.
>>
>> "Although the interfaces for administered objects do not explicitly depend
>> on JNDI, JMS establishes the convention that
>> JMS clients find them by looking them up in a namespace using JNDI.
>>
>> "An administrator can place an administered object anywhere in a
>> namespace. JMS does not define a naming policy.
>>
>> "This strategy of partitioning JMS and administration provides several
>> benefits:
>>
>> • It hides provider-specific configuration details from JMS clients.
>> • It abstracts JMS administrative information into Java objects that are
>> easily organized and administered from a common
>> management console.
>> • Since there will be JNDI providers for all popular naming services, this
>> means JMS providers can deliver one
>> implementation of administered objects that will run everywhere.
>>
>> "An administered object should not hold on to any remote resources. Its
>> lookup should not use remote resources other
>> than those used by JNDI itself.
>>
>> "Clients should think of administered objects as local Java objects.
>> Looking them up should not have any hidden side
>> effects or use surprising amounts of local resources.
>>
>> "JMS defines two administered objects, Destination and ConnectionFactory.
>>
>> "It is expected that JMS providers will provide the tools an administrator
>> needs to create and configure administered
>> objects in a JNDI namespace. JMS provider implementations of administered
>> objects should be both
>> javax.naming.Referenceable and java.io.Serializable so that they can be
>> stored in all JNDI naming contexts. In addition,
>> it is recommended that these implementations follow the JavaBeans design
>> patterns."
>>
>>
>>