users@jms-spec.java.net

[jms-spec users] [jsr343-experts] Re: (JMS_SPEC-89) Define standard API to create and configure a ConnectionFactory in Java SE applications and by a Java EE container

From: John D. Ament <john.d.ament_at_gmail.com>
Date: Tue, 27 Mar 2012 06:45:45 -0400

My feedback would be that the API should be more like:

Properties props = new Properties();
props.setProperty("connectionFactoryClassName","com.acmejms.AcmeConnectionFactory"};
props.setProperty("url","jms://localhost:1234"};
props.setProperty("user","admin"};
props.setProperty("password",password);
ConnectionFactory cf = javax.jms.ConnectionFactories.getReference(props);

I would prefer a cleaner API though - either an equivalent getReference
that took in the actual values, or took in a Map. I would also prefer if
we really needed the connectionFactoryClassName (which, I would think we
don't really need) that it could be an actual class, not a string.

John


On Tue, Mar 27, 2012 at 6:05 AM, Nigel Deakin <nigel.deakin_at_oracle.com>wrote:

> I have logged this JIRA issue:
> http://java.net/jira/browse/**JMS_SPEC-89<http://java.net/jira/browse/JMS_SPEC-89>
>
> This replaced JMS_SPEC-46 which I have withdrawn and closed.
>
> Description follows (this is best viewed in JIRA). Comments please.
>
> Define standard API to create and configure a ConnectionFactory in Java SE
> applications and by a Java EE container
> ------------------------------**------------------------------**
> ------------------------------**------------------------
>
> This is a proposal to extend the JMS specification to define a standard
> way of instantiating and configuring connection factory objects.
>
> The proposal below is intended to be used by Java SE applications and by
> Java EE container code such as resource adapters, but not by Java EE
> applications themselves. This is not intended to provide an alternative to
> Java EE configuration via JNDI.
>
> It replaces the proposal made in JMS_SPEC-46 and is being logged as a
> separate JIRA issue to avoid confusion.
>
> 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 JMS 1.1 specification section 2.3
> "Administration").
>
> 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
>
> * it means that a generic JMS resource adapter, which wraps the connection
> factories of third-party JMS providers, cannot instantiate those connection
> factories directly but must instead look then up from JNDI
>
> * it requires Java SE applications which use JMS to use JNDI as the only
> way to keep provider-specific configuration separate from their code.
> Applications cannot manage configuration their own way, such as by using
> properties files.
>
> h4. Proposed standard for instantiating a connection factory and setting
> properties
>
> It is proposed that for Java SE applications, and for Java EE container
> code only, but not for Java EE applications, a ConnectionFactory can be
> instantiated and configured by invoking a constructor which takes a
> Properties object as an argument:
>
> {noformat}
> Properties props = new Properties();
> props.setProperty("url","jms:/**/localhost:1234"};
> props.setProperty("user","**admin"};
> props.setProperty("password",**password);
> ConnectionFactory cf = new com.acme.jms.**AcmeConnectionFactory(**properties
> props);
> {noformat}
>
> Note that since properties are passed into the constructor rather than be
> set after the object has been created in order this allows connection
> factories to be implemented as immutable objects which cannot be changed
> after creation. That's why this proposal does not suggest setting
> properties directly on the connection factory.
> (Another reason why this proposal does not suggest setting properties
> directly on the connection factory is that it would require changes to the
> javax.jms.ConnectionFactotry interface which would be inappropriate for
> connection factories in a Java EE environment.)
>
> Even though this approach is intended to avoid the need to use JNDI it
> remains the goal of JMS to allow the creation of applications which are
> portable between JMS providers. This means that declaring provider-specific
> classes in the application is discouraged. Instead, a new utility class
> javax.jms.**ConnectionFactoryCreator will be provided by JMS which allows
> the provider-specific connection factory class name to be passed in as just
> another property. This could be used as follows:
>
> {noformat}
> Properties props = new Properties();
> props.setProperty("**connectionFactoryClassName","**com.acmejms.**
> AcmeConnectionFactory"};
> props.setProperty("url","jms:/**/localhost:1234"};
> props.setProperty("user","**admin"};
> props.setProperty("password",**password);
> ConnectionFactory cf = new javax.jms.**ConnectionFactoryCreator(**properties
> props);
> {noformat}
>
> In the above example, the property values are hardcoded just to make the
> example clearer. However it would be recommended that they be defined
> separately from the application.
>
> Why is this not proposed for Java EE applications?
> ------------------------------**--------------------
>
> Note that this proposal does not cover Java EE applications. This is
> because in the Java EE web and application container a connection factory
> cannot be created in isolation because it needs to participate in the
> connection pooling facilities of the container. The JCA API defines two
> methods on javax.resource.spi.**ManagedConnectionFactory to create a
> connection factory: createConnectionFactory() and createConnectionFactory(
> **ConnectionManager cxManager).
>
> This also provides another reason why the above proposal passes properties
> to the connection factory constructor rather than allowing them to be set
> on the connection factory instance. If we had allowed the latter this would
> have added new methods to the Connectionfactory interface whose use we
> would have needed to explicitly disallow for Java EE applications.
>
> Proposed standard properties:
> -----------------------------
>
> The following standard connection factory properties are proposed:
>
> Property name Type Description
> 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)
> clientId String clientId that will be used when a connection is
> created
> url String Opaque string which defines how to connect to the
> JMS provider
>
> This proposal deliberately keeps the list of standard properties to a bare
> minimum, and abandons the longer list proposed in JMS_SPEC-46. It is
> expected that JMS providers will define their own additional properties.
>
>
>