jsr343-experts@jms-spec.java.net

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

From: Nigel Deakin <nigel.deakin_at_oracle.com>
Date: Wed, 29 Feb 2012 12:34:16 +0000

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