users@jms-spec.java.net

[jms-spec users] [jsr343-experts] Re: Re: (JMS_SPEC-70) Define annotations for injecting MessagingContext objects

From: Rüdiger zu Dohna <ruediger.dohna_at_1und1.de>
Date: Tue, 14 Feb 2012 12:33:04 +0100

Nigel,

Thinking about it again, I assume that the transaction scope would not be appropriate. There are a number of values (client id, delivery mode/delay, priority, time-to-live, etc.) that you can set on a messaging context. Any scope other that dependent would mean, that these settings would be shared between several bean instances... not what users would expect, would they? So I think we're bound to use DependentScope.

It could well be that the transaction or some other scope would be helpful to implement the actual connection pooling, though.


Rüdiger

On 2012-02-14, at 11:57, Nigel Deakin wrote:

> Rüdiger,
>
> I think that at the very least the default scope behaviour needs to be specified in the spec (if it wasn't then
> applications that used it might not always be portable).
>
> I suggested the default scope as being request scope (but with a separate instance for each injection point, even within
> the same scope) because I know this can be implemented using CDI. If CDI offers some new built-in scope, such as method
> scope or transaction scope, we could consider making that the default instead.
>
> I'm open to extending the spec to allow other built-in scopes to be used, though I'm not sure exactly what this would
> look like.
>
> And I'm open to allowing the application to define its own scopes, though again I'd welcome suggestions on what the spec
> would need to say to support this.
>
> Nigel
>
> On 13/02/2012 20:06, Rüdiger zu Dohna wrote:
>> Nigel,
>>
>> It would be easiest to implement, if a TransactionScope was available. But if the MessagingContext was
>> DependentScope, then just the actual connection pooling would have to be implemented "by hand". So, if the spec wants
>> to specify the scope of the implementation, it should explain why. Thinking about it, maybe it would be better to
>> just describe the behavior and leave the actual scope up to the implementation.
>>
>>
>> Rüdiger
>>
>> On 2012-02-13, at 19:36, Nigel Deakin wrote:
>>
>>> Rüdiger,
>>>
>>> You wrote "I think it would be useful, if the spec would explain, why you'd want to have a scope other than
>>> dependent"
>>>
>>> What you have described corresponds to how a MessagingContext would behave if it was transaction-scoped.
>>>
>>> Nigel
>>>
>>>
>>> On 13/02/2012 14:59, Rüdiger zu Dohna wrote:
>>>> Nigel,
>>>>
>>>> The MessagingContext only needs a _logical_ connection, doesn't it? The _physical_ connection can be taken out of
>>>> the pool when it enters a transaction context, and put back, when it leaves (by commit or rollback). IIRC, any
>>>> guarantees about message order, etc., are only given within one transaction, so pooling the physical connection
>>>> after a commit with the MessagingContext instance still in place would comply, wouldn't it?
>>>>
>>>>
>>>> Regards Rüdiger
>>>>
>>>> On 2012-02-13, at 13:56, Nigel Deakin wrote:
>>>>
>>>>> Rüdiger,
>>>>>
>>>>> If MessagingContext were dependent scope then it would exist for the lifetime of the component which declared
>>>>> it. So for a session bean this might be for the entire lifetime of the application server. Whilst this might
>>>>> work in JMS terms it would defeat the connection pooling of the application server. It would mean that even an
>>>>> inactive session bean instance would be holding on to JMS connections, and so increase the number of
>>>>> connections used overall. I think we need a scope that supports the recommended Java EE pattern of obtaining a
>>>>> connection from the pool, using it, and returning the connection to the pool as soon as possible.
>>>>>
>>>>> Nigel
>>>>>
>>>>> On 13/02/2012 06:33, Rüdiger zu Dohna wrote:
>>>>>> I think it would be useful, if the spec would explain, why you'd want to have a scope other than dependent...
>>>>>> it's not really obvious. As long as only one bean with a MessagingContext is involved, dependent scope would
>>>>>> be just fine. Only when different beans with their own MessagingContext are involved, it is useful, if they
>>>>>> can share one context within the same transaction, so message-ordering, etc. work as you would expect. I
>>>>>> assume this to be not the standard case, so the extra complexity may not be expected.
>>>>>>
>>>>>>
>>>>>> On 2012-02-11, at 16:39, John D. Ament wrote:
>>>>>>
>>>>>>> I've been thinking on this subject a bit. I think the issue is that for JMS to work right with injection
>>>>>>> and annotations, the annotations need to act like the annotations in JPA when injection is supported (e.g.
>>>>>>> @PersistenceContext). I don't think CDI has this supported quite well yet. Pete, any comment on this?
>>>>>>>
>>>>>>> John
>>>>>>>
>>>>>>>
>>>>>>> On Wed, Feb 8, 2012 at 10:27 AM, Nigel Deakin<nigel.deakin_at_oracle.com<mailto:nigel.deakin_at_oracle.com>>
>>>>>>> wrote:
>>>>>>>
>>>>>>> I created this new issue a couple of days ago to allow us to track the injection of MessagingContext
>>>>>>> objects separately from the rest of the simplified API:
>>>>>>> http://java.net/jira/browse/__JMS_SPEC-70<http://java.net/jira/browse/JMS_SPEC-70>
>>>>>>>
>>>>>>> Currently, the simplified API is in the Early Draft but the injection of MessagingContext objects is not.
>>>>>>> However if there is general agreement on what is proposed below I propose to include this in the Early
>>>>>>> Draft as well (since supporting this was the main reason for defining the simplified API):
>>>>>>>
>>>>>>> Any comments? (If you don't understand what I am proposing, please let me know either directly or via the
>>>>>>> list)
>>>>>>>
>>>>>>> If it's hard to read the text below, the same content may be found in the JIRA issue.
>>>>>>>
>>>>>>> I described the requirement as follows:
>>>>>>>
>>>>>>> ------------------------------__-------------------------- The simplified API (JMS_SPEC-64) defines a
>>>>>>> single object, javax.jms.MessagingContext, which provides methods for sending and receiving messages.
>>>>>>>
>>>>>>> It is proposed that the JMS API define some standard annotations that can be used to inject
>>>>>>> MessagingContext objects into application code.
>>>>>>>
>>>>>>> * The injection point should allow the application define the two parameters needed to create a
>>>>>>> MessagingContext: JNDI name (of the connection factory) and sessionMode. Both should be optional with
>>>>>>> suitable defaults.
>>>>>>>
>>>>>>> * The implementation should ideally be implemented using CDI and have behaviour consistent with it. However
>>>>>>> this is not essential.
>>>>>>>
>>>>>>> * It must be possible to use injection in Java EE applications. It is desirable but not essential to be
>>>>>>> able to use injection in Java SE applications.
>>>>>>>
>>>>>>> * Injected MessagingContexts must have an appropriate scope and must be automatically closed when they fall
>>>>>>> out of scope. ------------------------------__--------------------------
>>>>>>>
>>>>>>> I've now drafted a new section for the JMS spec that defines how users will inject MessagingContext
>>>>>>> objects. I've added this text, and the proposed new annotation interfaces, to the JIRA issue:
>>>>>>> http://java.net/jira/browse/__JMS_SPEC-70<http://java.net/jira/browse/JMS_SPEC-70>
>>>>>>>
>>>>>>> I've pasted the same text below. (To see the actual annotation definitions, see the JIRA issue).
>>>>>>>
>>>>>>> I'd like to thank Pete Muir, CDI spec lead, helping me define a mechanism for injecting MessagingContext
>>>>>>> objects which * Allow JNDI name and sessionMode to be specified in the injection point * Ensures injected
>>>>>>> objects are closed at the end of the request * Is consistent with CDI style * Is capable of being
>>>>>>> implemented
>>>>>>>
>>>>>>> I have a working prototype which implements this, based on a proposal from Pete, and which I'm happy to
>>>>>>> share.
>>>>>>>
>>>>>>> I'd also like to acknowledge the help I was given earlier by Reza (Rahman) and John (Ament).
>>>>>>>
>>>>>>> ------------------------------__--------------------------
>>>>>>>
>>>>>>> This section relates to application classes which run in the Java EE web, EJB or application client
>>>>>>> containers and which support injection. Section EE.5 of the Java EE specification lists the application
>>>>>>> classes that support injection.
>>>>>>>
>>>>>>> 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.
>>>>>>>
>>>>>>> The annotation javax.jms.JMSConnectionFactory may be used to specify the JNDI lookup name of the
>>>>>>> ConnectionFactory used to create the messaging context. For example:
>>>>>>>
>>>>>>> @Inject @JMSConnectionFactory("jms/__connectionFactory") private MessagingContext context;
>>>>>>>
>>>>>>> If no lookup name is specified or the JMSConnectionFactory annotation is omitted then the platform default
>>>>>>> JMS connection factory will be used.
>>>>>>>
>>>>>>> The annotation javax.jms.JMSSessionMode may be used to specify the session mode of the messaging context:
>>>>>>>
>>>>>>> @Inject @JMSConnectionFactory("jms/__connectionFactory")
>>>>>>> @JMSSessionMode(__MessagingContext.AUTO___ACKNOWLEDGE) private MessagingContext context;
>>>>>>>
>>>>>>> The meaning and possible values of session mode are the same as for the ConnectionFactory method
>>>>>>> createMessagingContext(int sessionMode):
>>>>>>>
>>>>>>> * In the Java EE application client container, session mode may be set to any of
>>>>>>> MessagingContext.SESSION___TRANSACTED, MessagingContext.CLIENT___ACKNOWLEDGE,
>>>>>>> MessagingContext.AUTO___ACKNOWLEDGE or MessagingContext.DUPS_OK___ACKNOWLEDGE. If no session mode is
>>>>>>> specified or the JMSSessionMode annotation is omitted a session mode of MessagingContext.AUTO___ACKNOWLEDGE
>>>>>>> will be used.
>>>>>>>
>>>>>>> * In a Java EE web or EJB container, when there is an active JTA transaction in progress, session mode is
>>>>>>> ignored and the JMSSessionMode annotation is unnecessary.
>>>>>>>
>>>>>>> * In a Java EE web or EJB container, when there is no active JTA transaction in progress, session mode may
>>>>>>> be set to either of MessagingContext.AUTO___ACKNOWLEDGE or MessagingContext.DUPS_OK___ACKNOWLEDGE. If no
>>>>>>> session mode is specified or the JMSSessionMode annotation is omitted a session mode of
>>>>>>> MessagingContext.AUTO___ACKNOWLEDGE will be used.
>>>>>>>
>>>>>>> For more information about the use of session mode when creating a messaging context, see section 10.3 of
>>>>>>> the JMS 2.0 Early Draft, "Behaviour of JMS sessions in the Java EE web or EJB container" and the API
>>>>>>> documentation for the ConnectionFactory method createMessagingContext(int sessionMode).
>>>>>>>
>>>>>>> ------------------------------__--------------------------
>>>>>>>
>>>>>>> Here are three simple examples:
>>>>>>>
>>>>>>> 1. Sending a TextMessage in a Java EE web or EJB container.
>>>>>>>
>>>>>>> @Inject @JMSConnectionFactory("jms/__connectionFactory") private MessagingContext messagingContext;
>>>>>>>
>>>>>>> @Resource(mappedName = "jms/inboundQueue") private Queue inboundQueue;
>>>>>>>
>>>>>>> public void sendMessageNew(String payload) { messagingContext.send(__inboundQueue, payload); }
>>>>>>>
>>>>>>> 2. Receiving a message synchronously in a Java EE web or EJB container.
>>>>>>>
>>>>>>> @Inject @JMSConnectionFactory("jms/__connectionFactory") private MessagingContext messagingContext;
>>>>>>>
>>>>>>> @Resource(lookup="jms/__inboundQueue") Queue inboundQueue;
>>>>>>>
>>>>>>> public String receiveMessageNew() { SyncMessageConsumer syncMessageConsumer =
>>>>>>> messagingContext.__createSyncConsumer(__inboundQueue); return
>>>>>>> syncMessageConsumer.__receivePayload(String.class); }
>>>>>>>
>>>>>>> 3. Receiving a message synchronously from a durable subscription in a Java EE web or EJB container.
>>>>>>>
>>>>>>> @Inject @JMSConnectionFactory("jms/__connectionFactory2") private MessagingContext context;
>>>>>>>
>>>>>>> @Resource(lookup="jms/__inboundTopic") Topic inboundTopic;
>>>>>>>
>>>>>>> public String receiveMessageNew() { SyncMessageConsumer syncMessageConsumer =
>>>>>>> context.__createSyncDurableConsumer(__inboundTopic, "mysub"); return
>>>>>>> syncMessageConsumer.__receivePayload(String.class); }
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>