users@jms-spec.java.net

[jms-spec users] Re: Confusion about JMSProducer methods and CDI

From: Elias Ross <genman_at_noderunner.net>
Date: Mon, 9 Jun 2014 11:46:21 -0700

On Mon, Jun 9, 2014 at 3:40 AM, Nigel Deakin <nigel.deakin_at_oracle.com> wrote:

> As you have spotted, in the RI the JMSContextImpl object contains a cached
> MessageProducer object. When the JMSProducer's send() method is called, all
> the properties set on that JMSProducer (including timeToLive) are copied to
> this MessageProducer object, and then this MessageProducer object is used to
> send the message.

Okay, it looks as if JMSContext is not shared between threads, then it
should do the right thing, as it's always replacing the existing
settings of the cached MessageProducer with new ones.

HornetMQ has the bug.

>>
>> The other question I had was the scoping for CDI. For example:
>>
>> @ApplicationScoped
>> public class MyClient {
>> @Inject JMSContext context;
>> }
>>
>> public class MyServlet extends HttpServlet {
>> @Inject MyClient client;
>> }
>>
>> Then JMSContext ends up being potentially shared between multiple
>> threads. I would expect the scoping of JMSContext to be request, not
>> @Dependent here.
>>
>
> Why do you say that the "JMSContext ends up being potentially shared between
> multiple threads"?
>
> The scope of the injected JMSContext is defined in the JMS 2.0 spec, section
> 12.4.4. "Scope of injected JMSContext objects". Essentially, if there's a
> transaction in progress then the injected JMSContext will have transaction
> scope, otherwise it will have request scope.
>
> It looks like you're in a servlet here, and you haven't started a
> transaction, so the injected JMSContext must have request scope.

So this is probably a bug in WildFly as well, as the producer looks like this:

package org.jboss.as.messaging.deployment;

public class JMSContextProducer {

   /**
     * CDI Producer method for injected {_at_link JMSContext}.
     */
    @Produces
    public JMSContext getJMSContext(InjectionPoint injectionPoint)
throws NamingException {

Which means the @Dependent scope is used incorrectly. In CDI I'm not
sure how to create a producer that changes scope based on state
information, although I suppose it could be done using some sort of
CDI extension.