jsr343-experts@jms-spec.java.net

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

From: Reza Rahman <reza_rahman_at_lycos.com>
Date: Tue, 20 Sep 2011 20:33:43 -0400

Nigel,

Personally, I never expected that this would have much practical use in
Java EE, just like JDBC driver managers.

Cheers,
Reza


On 9/19/2011 10:36 AM, Nigel Deakin wrote:
> Dear all,
>
> On 16/09/2011 16:32, Nigel Deakin 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
>>>
>>> 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
>
> I've been thinking more about how my proposal would work in a Java EE
> environment where the JMS connection factory is provided by the
> resource adapter, not the underlying JMS provider.
>
> In such an environment, the connection factory is provided by the
> resource adapter and is created by calling one of two
> createConnectionFactory methods on the
> javax.resource.spi.ManagedConnectionFactory:
>
> This typically happens as part of the JNDI lookup. The
> ManagedConnectionFactory instance is implemented by the resource
> adapter and is required to be a JavaBean.
>
> So I think my suggestion that the connection factory would be defined
> and instantiated simply by using a no-arg constructor may be too
> simplistic (though it may be OK for Java SE). I'll need to investigate
> this further, but for now I'd like to withdraw the proposal that a
> connection factory be created using a no-arg constructor.
>
> However I think all the other proposals, which define a set of
> standard properties for connection factories, can probably still stand.
>
> One of the reasons I think these are needed is that, separately, the
> Java EE Expert Group is discussing whether to allow connection
> factories to be defined in JNDI using @JMSConnectionFactoryDefinition
> annotations, analogous to @DataSourceDefinition annotations.
>
> These provide a standard way to *create* connection factories in JNDI,
> which is currently completely non-standard.
>
> The general idea of having this annotation is probably out of our
> scope, but might look something like this:
>
> @JMSConnectionFactoryDefinition(
> name="java:app/MyJMSFactory",
> resourceType="javax.jms.QueueConnectionFactory",
> resource-adapter="somera",
> clientId="foo",
> connectionTimeout=10,
> initialPoolSize=5,
> maxPoolSize=15
> )
>
> However the actual connection factory properties that can be defined
> are definitely within our scope to define (apart from those which are
> related to pooling).
>
> 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."
>>>
>>>
>
>
> -----
> No virus found in this message.
> Checked by AVG - www.avg.com
> Version: 10.0.1410 / Virus Database: 1520/3905 - Release Date: 09/18/11
>
>