users@jms-spec.java.net

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

From: Nigel Deakin <nigel.deakin_at_oracle.com>
Date: Wed, 07 Mar 2012 15:25:13 +0000

Pete,

(I only just saw this, so it crossed with my direct mail to you yesterday)

Can you give a pointer to Rick Hightower's proposal for transaction scope?

The kind of thing I'm interested in is:

1. What scope would injected @TransactionScoped objects have if there was no transaction?
2. Would @TransactionScoped work with both bean-managed as well as container-managed transactions (i.e. when the
transaction boundary occurs part-way through a method)?
3. When a transaction boundary occurs part-way through a method, what scope is used for injected objects used before the
transaction is started or after it is committed?
4. Does @TransactionScoped support transactions that span multiple requests?

The other important issue is whether we can use annotations like "@Inject @JMSConnectionFactory(lookup"jms/foo")" with
@TransactionScoped. (I know we can't with request scope). If not, JMS couldn't use it directly and we'd need to use a
workaround similar to the one you suggested for simulating request scope.

Nigel


On 06/03/2012 16:38, Pete Muir wrote:
> That sounds like a good way to proceed. Rick Hightower has a basic proposal for transaction scope if you want to pick up the ball from him.
>
> On 6 Mar 2012, at 01:48, John D. Ament wrote:
>
>> Nigel,
>>
>> So I think this is going to be an issue if we are aiming for CDI support. We may need to define a scoping require, and I think if we formally build our proposal, we can get it in front of the CDI EG for their review.
>>
>> John
>>
>> On Wed, Feb 29, 2012 at 7:34 AM, Nigel Deakin<nigel.deakin_at_oracle.com> wrote:
>> John,
>>
>>
>> On 29/02/2012 00:21, John D. Ament wrote:
>>> Nigel,
>>>
>>> My preference would be to delegate the ideas of how many and scoping to simply refer to the CDI specifications, noting that the injected messaging context is @Dependent or @RequestScoped (not sure which was agreed to, if any?)
>> Thanks for your comments. The problem with simply delegating the specification of this feature to the CDI spec is that CDI doesn't actually define, or allow, the behaviour I think we need. In particular:
>>
>> An annotation like "@Inject @JMSConnectionFactory(lookup"jms/foo")" is only possible in CDI if the scope is dependent (as I'm sure you remember). However a dependent scope object has a lifetime (between creation and disposal) which might be as long as the app server, whereas I think we want to allow (and encourage) the container to dispose of the object when it wasn't needed, such as at the end of a transaction or request, since a MessagingContext is a limited resource.
>>
>> CDI does define request scope (even if we can't use it with our particular annotations). However JMS may require something slightly different, perhaps a hybrid of request or transaction scope to cater for the case where a transaction spans multiple requests. I don't have a definite view of what is needed, but I think it is reasonable to discuss what is needed for JMS and, if necessary, propose that CDI be enhanced to support it.
>>
>> I think there are some similarities with the @PersistenceContext annotation (which isn't a CDI injection and offers a kind of transaction scope) though I was looking for something simpler and closer to standard CDI if possible.
>>
>> Nigel
>>
>> (For the avoidance of confusion, this is what I suggested in yesterday's email)
>>
>>
>> "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.
>>
>>
>>> John
>>>
>>>
>>> On Tue, Feb 28, 2012 at 1:47 PM, Nigel Deakin<nigel.deakin_at_oracle.com> wrote:
>>> 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
>>>
>>>