users@jms-spec.java.net

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

From: John D. Ament <john.d.ament_at_gmail.com>
Date: Mon, 5 Mar 2012 20:48:25 -0500

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
>>
>>
>