users@jms-spec.java.net

[jms-spec users] [jsr343-experts] Re: JMS 2.0 Early Draft ready for final review

From: Nigel Deakin <nigel.deakin_at_oracle.com>
Date: Tue, 28 Feb 2012 18:47:26 +0000

Returning to this thread...

On 20/02/2012 18:15, Rüdiger zu Dohna wrote:
> On 2012-02-20, at 14:45, Nigel Deakin wrote:
>>>>> * Injecting a MessagingContext ------------------------------
>>> But we don't have to specify that there has to be some underlying MessagingContext, do we?
>>
>> We have to say *something* because we don't want the application to think that the instance variable holding the
>> MessagingContext will correspond to the same session for the entire life of the owning bean (because that would
>> have implications for message ordering). I'm still looking for the right form of words here and am open to
>> suggestions.
>
> IMHO, if message ordering was only defined within one transaction, that would be good enough. This is the 99,99% use
> case in EE and a useful simplification in SE, isn't it?

Just to step back a little, I'm still trying to think of what the spec needs to say about how injected MessagingContext
objects are managed.

I think there are two separate but related concepts:

1. The lifetime of the MessagingContext that is injected at a given injection point.

2. Whether multiple injection points will get the same or different MessagingContext objects.

I'll explore these in turn:

1. The lifetime of the MessagingContext that is injected at a given injection point.
------------------------------------------------------------------------------------

If I have, say, a stateful session bean with an injected MessagingContext:


@Inject MessagingContext context;

public void doSomething(payload){
    context.send(payload);
}

When an application makes two calls to doSomething(), the application needs to know whether the two calls are guaranteed
to use the same MessagingContext or whether they might use different MessagingContexts. Only when they use the same
MessagingContext does JMS guarantee that the messages will be delivered in order.

I don't think it is reasonable to require the container to provide the same MessagingContext every time for the whole
lifetime of the application. However I do think it would be reasonable for the container to provide the same
MessagingContext for the duration of the request, or the duration of the transaction, whichever of the two is longer.

We could leave it up to the container to decide whether it wants to keep the same MessagingContext for longer than that,
though a well-designed container would silently close the MessagingContext when it was not being used and create a new
MessagingContext when needed.

2. Whether multiple injection points will get the same or different MessagingContext objects.
---------------------------------------------------------------------------------------------

This is about whether two different @Inject statements, perhaps in different beans, should return the same
MessagingContext object.

Consider one bean that calls another:

@Stateless
public class Bean1{

    @Resource(lookup="jms/inboundQueue") Queue inboundQueue;
    @Inject MessagingContext context;
    @EJB Bean1 bean2;

    public void doSomething(String payload){
       context.send(inboundQueue,payload);
       bean2.doSomethingElse("Finished");
    }
}

@Stateless
public class Bean2{

    @Resource(lookup="jms/inboundQueue") Queue inboundQueue;
    @Inject MessagingContext context;

    public void doSomethingElse(String payload){
       context.send(inboundQueue,payload);
    }
}

The question is: are the injected MessagingContext objects actually the same?

My proposal in the draft specification stated that they would not be the same.

However I have had second thoughts, and I think it would be valuable if the spec specified that if the two objects were
being used in the same request, or the same transaction, whichever is longer, and the @Inject statements specified the
same connection factory and other annotations, then the two objects would be the same.

3. What the spec could say
--------------------------

In the JMS 2.0 Early Draft I proposed (section 11.3 "Injection of MessagingContext objects") that:

-----
"Applications may declare a field of type javax.jms.MessagingContext and annotate it with the javax.inject.Inject
annotation:

"@Inject private MessagingContext context;

"The container will inject a MessagingContext. It will have request scope and will be automatically closed when the
request ends. However, unlike a normal CDI request-scoped object, a separate MessagingContext instance will be injected
for every injection point."
-----

I'd like to propose an alternative wording as follows:

-----
"Applications may declare a field of type javax.jms.MessagingContext and annotate it with the javax.inject.Inject
annotation:

"@Inject private MessagingContext context;

"The container will inject a container-managed MessagingContext whose lifetime will be managed by the container and
which is scoped to a single transaction or a request, whichever is longer. An injected MessagingContext with a given set
of annotations will be propagated by the container to other injection points with the same annotations in the same
transaction or request, whichever is longer.
-----

(I've stolen some of this terminology from the JPA spec)

This implies a scope which is "transaction or request, whichever is longer". I'm unsure of whether this is quite right
(and I don't know how to implement it yet): I would have simply mentioned a scope of just "transaction", except that
this needs to work when there is no transaction as well.

Nigel