users@jms-spec.java.net

[jms-spec users] [jsr343-experts] Re: Re: (JMS_SPEC-90) Provide simpler mechanism to refer to queues and topics in a portable way

From: John D. Ament <john.d.ament_at_gmail.com>
Date: Fri, 20 Apr 2012 09:46:35 -0400

Nigel,

I'm not a fan of either approach (EE is maybe doable). Defining a standard
implementation as a part of the JMS API seems awkward. You're forcing the
implementers to write code in a fashion that is mandated by JMS.

I'm not sure I follow why keying it off connection factory is poor, or even
having a static method available in some class?

John

On Fri, Apr 20, 2012 at 9:16 AM, Nigel Deakin <nigel.deakin_at_oracle.com>wrote:

> My earlier proposals for some new API to create Queue and Topic objects
> didn't gain much support from this EG. I've thought about this more,
> discussed it with colleagues, and come up with a new proposal.
>
> What am I trying to achieve here is to allow any application (including
> Java SE or Java EE applications, a Java EE container, a resource adapter,
> and tools) to create a Queue or Topic object in a portable way without the
> need to obtain a connection factory, connection or session first.
>
> I did consider adding new API to connection factory, but this introduces a
> dependency on a vendor's JMS implementation which is actually not
> necessary. JMS already defines a Queue or Topic object to be simply a
> wrapper around a provider-specific queue or topic name, and I think we
> should keep it as that.
>
> I also considered whether we should make the use of Queue and Topic
> objects unnecessary by adding new methods to JMS which simply took a String
> name instead of a Queue and Topic. I decided this was undesirable for two
> reasons: it would bloat the API with yet more methods, but more importantly
> because the concept of a Queue and Topic object remains a useful one in JMS
> (and Java EE) because by allowing Queue and Topic objects to be bound in
> JNDI it allows application code to be separated from queue and topic names.
>
> Below are two separate proposals: a new feature in JMS, and a tentative
> proposal for Java EE which exploits this feature. (We would need to discuss
> the latter in detail with the Java EE platform spec EG).
>
> Please give your comments or questions on both (A) and (B).
>
> A: JMS Proposal
> ---------------
>
> I propose that JMS defines two classes: javax.jms.QueueImpl (which
> implements the javax.jms.Queue interface) and javax.jms.TopicImpl (which
> implements the javax.jms.Topic interface). These are classes, whose
> implementation is provided by JMS.
>
> Here is what javax.jms.QueueImpl would look like:
>
> public final class QueueImpl implements Queue {
> String queueName;
> public QueueImpl(String queueName) {
> this.queueName = queueName;
> }
> public String getQueueName() throws JMSException {
> return queueName;
> }
> }
>
> javax.jms.TopicImpl would be similar.
>
> So an application could create a Queue by calling
>
> Queue queue = new QueueImpl("myQueue");
>
> We would then define that any existing JMS API call which accepted a
> javax.jms.Destination must be able to accept a QueueImpl or TopicImpl, any
> existing JMS API call which accepted a javax.jms.Queue must be able to
> accept a QueueImpl, and any existing JMS API call which accepted a
> javax.jms.Topic must be able to accept a TopicImpl.
>
> This would be very simple for vendors to implement, since they can simply
> use the existing createQueue/createTopic methods on Session (which they
> already implement) to convert the queue or topic name to whatever
> provider-specific class they currently use to implement Queue and Topic.
>
> For example, the implementation of Session.createConsumer would need to be
> modified as follows:
>
> Existing implementation:
>
> public MessageConsumer createConsumer(Destination destination) throws
> JMSException {
> return someProprietaryCodeToCreateCon**sumer(destination);
> }
>
> New implementation:
>
> public MessageConsumer createConsumer(Destination destination) throws
> JMSException {
> if (destination instanceof QueueImpl){
> return someProprietaryCodeToCreateCon**
> sumer(createQueue(destination.**getQueueName());
> } else if (destination instanceof TopicImpl){
> return someProprietaryCodeToCreateCon**
> sumer(createTopic(destination.**getTopicName());
> } else {
> return someProprietaryCodeToCreateCon**sumer(destination);
> }
> }
>
> Some minor details:
>
> * We would need to define that it was valid to pass a QueueImpl or
> TopicImpl into Message.setJMSReplyTo, though Message.getJMSReplyTo would be
> free to return a proprietary implementation.
>
> * We would clarify that implementations of Session.createQueue/**createTopic
> and Message.getJMSReployTo would be free to return a proprietary
> implementation of Queue or Topic in all cases, or they could return a
> QueueImpl or TopicImpl.
>
> B: Java EE Proposal
> -------------------
>
> The above change would make it possible to consider some new features for
> Java EE. This is because for the first time it would be possible for a Java
> EE container to inject a Queue or Topic object without the need to use JMS
> provider code.
>
> It is proposed that we define some default behaviour when injecting a
> Queue or Topic object into a Java EE application.
>
> An application can currently inject a Queue object as follows:
>
> @Resource(name="myQueueName")
> Queue myQueue;
>
> Java EE states that the name attribute is used to specify a "destination
> reference name". The application deployer is responsible for creating a
> Queue object, binding it to some location of JNDI, and providing a
> <message-destination-ref> element which maps the specified name to the JNDI
> name of the Queue object. If there is no such mapping, or if there is no
> such JNDI object, a deployment error occurs.
>
> We could propose that if the specified destination reference name is not
> mapped to a JNDI name then the container will automatically instantiate a
> QueueImpl, using the specified destination reference name as the queue
> name, and inject it into the application.
>
> This would offer a much simpler way to configure destinations for
> applications, whilst leaving unchanged the ability of a deployer to
> override this behaviour by defining a <message-destination-ref> element in
> the normal way.
>
> Note that the Java EE 7 Early Draft already proposes a way for a container
> to inject a "platform default connection factory". These two features
> together will significantly simply the use of JMS for smaller or less
> complex applications.
>
> There are a few details related to this Java EE proposal that would need
> to be considered:
>
> * We may want to define some similar default behaviour for MDBs.
>
> * We would need to check whether there were any restrictions on valid
> characters in @Resource(name="..."), since this would limit the queue or
> topic names that could be specified in this way.
>
> * This wouldn't be possible the application injected a Destination rather
> than a Queue or Topic, since the container wouldn't know whether to create
> a QueueImpl or a TopicImpl.
>
> Nigel
>
>