Nigel,
So a few things. I guess I made the assumption that create == retrieve. I
suppose there could be a difference - for example, looking up via JNDI
gives you a remote object reference, but instantiating the connection
factory in activemq is creating the implementation of connection factory.
When I was using getReference, it was really pointing out that it could be
either - a remote object or an actually instantiated object. This could be
vendor specific.
See below for the rest.
John
On Tue, Mar 27, 2012 at 6:59 AM, Nigel Deakin <nigel.deakin_at_oracle.com>wrote:
> John,
>
> Thanks for the quick feedback!
>
>
> On 27/03/2012 11:45, John D. Ament wrote:
>
> 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 made a careless error in my proposal: I wrote:
>
> ConnectionFactory cf = new javax.jms.ConnectionFactoryCreator(properties props);
>
> which doesn't make sense. I meant to write:
>
> ConnectionFactory cf = javax.jms.ConnectionFactoryCreator.create(properties props);
>
> which is identical to your proposal except that you've suggested a
> different class and method name (I don't have strong views about that).
>
> I've corrected the JIRA issue.
>
> Why do you suggest "getReference"? I see this method as creating a new
> object (a connection factory), whereas you appear to be thinking of it
> differently.
>
>
>
> I would prefer a cleaner API though - either an equivalent getReference
> that took in the actual values, or took in a Map.
>
>
> Properties implements Map. However I think Properties is better because
> these it expects keys and values to be Strings, which is what I think is
> appropriate here (e.g. it allows properties to be read from a file or
> configured in a GUI)
>
>
>
Right, Properties implements Map (and extends Hashtable, thus requiring it
to be synchronized). Ideally, I would expect the argument to be
Map<String,Object>, or Map<String,String> which could be a properties
file. Note that properties is actually <Object, Object> type, harming some
of the type safety.
http://docs.oracle.com/javase/7/docs/api/java/util/Properties.html
> 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.
>
> If you have the class declared in the application then you can simply use
> its constructor, which is defined in the first part of the proposal.
>
> 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);
>
>
So would it be a new requirement that the constructor supports an argument
of properties or Map (as I am pushing above).
> Nigel
>
>
> 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
>>
>> 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.
>>
>>
>>
>