users@jms-spec.java.net

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

From: Rüdiger zu Dohna <ruediger.dohna_at_1und1.de>
Date: Tue, 24 Apr 2012 11:50:52 +0200

Nigel,

Currently a deployer has to create the physical destination, configure it, give it an address name, and put it into JNDI with a second name, so the client code can do the lookup.

In my eyes, dependency injection is supposed to reverse only those last two steps: The code defines a logical endpoint and the deployer binds it to the physical destination he creates for the application.

This would mean, that there are two options:
1) Auto-create a destinations to hold messages before they are bound, so the binding happens *after* the method runs and calls some send method.
2) Throw an exception if the endpoint is not bound (note that this behavior sounds ugly, but actually the same thing already happens, when the JNDI name is not bound).



If we are willing to go further down that road, another option would be to invert even more... I'm aware that this would be a huge change to the already proposed simplified API and would require a lot of rethinking again. The code could look like this:

@JMSEndpoint
@ConnectionFactory(...)
public JMSDestination destination;

public void sendMessage(String payload) {
    destination.send(payload);
}

The injection point would by default be identified by the application name, module name, bean name, and field name. The last three could be overridden by annotation attributes.

Deployment tools could scan the annotations and ask the deployer to create and bind the destinations required. This also could be automated in a cloud environment by adding some destination deployment descriptor that include the provider-specific destination address, destination type, queue length, etc. And to finish the round trip, these could also be set by annotations like @DestinationAddress("hostname/appname"), @DestinationType(QUEUE), @DestinationOption("queue-length", "1024").


Crazy, eh? ;-)
Rüdiger

On 2012-04-23, at 12:25, Nigel Deakin wrote:
> On 21/04/2012 23:18, Rüdiger zu Dohna wrote:
>>
>> I would like to replace both options with code like this:
>>
>> public void sendMessageNew(String payload) {
>> context.send("myQueue", payload);
>> }
>
> The problem with this is that it means that the queue name cannot be overridden by a deployer or administrator at some point in the future (without changing the code). JMS has always encouraged keeping queue and topic names out of the code but instead encapsulating them in administered objects which can be looked up from JNDI. My proposal (B) is an attempt to getting the best of both worlds by allowing the developer to hardcode a queue or topic name in the application but still allow it to be overridden by the deployer or administrator.
>
> My proposal B (if the Java EE folks allow it) would change this to
>
> @Resource(name="myQueue")
> Queue queue;
>
> public void sendMessageNew(String payload) {
> context.send(queue, payload);
> }
>
> This was a deliberate attempt to achieve the simplicity you were asking for (having queue and topic names in the code) without losing the ability of the deployer/administrator to override this.
>
>>
>> I'm very well aware that there is a huge difference between a JNDI name and the provider-specific destination name
>> passed into createQueue/Topic and returned by Queue.getQueueName/Topic.getTopicName. But I don't care! This distinction gives me no benefit, it only makes my life harder.
>>
>> I'm also aware that they have different name spaces: In the first example, the String is obviously unique within JNDI;
>> in the second, it must be unique to the JMS provider and destination type (actually, you can regard the type to be part of the address); in the third, it would have to be unique to the JMS provider. But that's not really a problem, is it?
>> We're talking about new methods, so there's not legacy code we have to consider.
>>
>> The destination name that I put into my code should be purely business driven, i.e., it should not have to adhere to the JNDI naming conventions (i.e., prefixes), nor to the addressing scheme the JMS provider might use. It actually sort of identifies the logical endpoint of the sender, not the physical destination where the messages go to... so when a physical queue is created, this endpoint has to be bound to that queue... conventions may even allow to do this on
>> demand... but creating physical destinations is a completely different topic.
>
> I'm a little confused where you're going with this. "The destination name that I put into my code should be purely
> business driven" seems to be a description of what JMS and Java EE tries to do right now. The application defines the
> queue or topic in terms of a "logical name", perhaps which relates to its role in the application, and the deployer or
> administrator maps that to the real queue or topic in the JMS server. Given that Java EE has chosen JNDI as the
> technology to do this across the whole platform I think we're stuck with it, but a naming hierarchy is a pretty flexible
> and easy-to-understand concept. The "prefixes" you mention are really to allow these logical names to have scopes
> (component, application, global etc) which seems a useful feature to me, and there is always a default.