[jboss-jira] [JBoss JIRA] (WFLY-3338) @Inject'ed JMSContext is not thread-safe
Brian Stansberry (JIRA)
issues at jboss.org
Thu Jul 10 16:53:26 EDT 2014
[ https://issues.jboss.org/browse/WFLY-3338?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Brian Stansberry updated WFLY-3338:
-----------------------------------
Assignee: Jeff Mesnil (was: Jason Greene)
Component/s: JMS
> @Inject'ed JMSContext is not thread-safe
> ----------------------------------------
>
> Key: WFLY-3338
> URL: https://issues.jboss.org/browse/WFLY-3338
> Project: WildFly
> Issue Type: Bug
> Security Level: Public(Everyone can see)
> Components: JMS
> Affects Versions: 8.0.0.Final
> Reporter: Rich DiCroce
> Assignee: Jeff Mesnil
>
> Section 12.4.4 of the JMS 2.0 spec says:
> {quote}
> If a method is called on an injected JMSContext when there is a JTA
> transaction (either bean-managed or container-managed), the scope of
> the JMSContext will be @TransactionScoped.
> {quote}
> This is not currently true in WildFly. As a test case, suppose you have the following two beans:
> {code}
> import javax.annotation.Resource;
> import javax.enterprise.context.ApplicationScoped;
> import javax.enterprise.inject.Instance;
> import javax.inject.Inject;
> import javax.jms.JMSContext;
> import javax.jms.Topic;
> import javax.transaction.Transactional;
> @ApplicationScoped
> @Transactional
> public class AppScopedBean {
>
> @Inject
> private JMSContext jmsCtx;
> //private Instance<JMSContext> jmsCtx;
> @Resource(lookup = "jms/topic/test")
> private Topic topic;
>
> public void sendMessage() {
> jmsCtx.createProducer().setDisableMessageID(true).setDisableMessageTimestamp(true).send(topic, "a message");
> //jmsCtx.get().createProducer().setDisableMessageID(true).setDisableMessageTimestamp(true).send(topic, "a message");
> }
> }
> {code}
> {code}
> import javax.annotation.Resource;
> import javax.enterprise.concurrent.ManagedThreadFactory;
> import javax.enterprise.context.ApplicationScoped;
> import javax.enterprise.context.Dependent;
> import javax.enterprise.context.Initialized;
> import javax.enterprise.event.Observes;
> import javax.inject.Inject;
> @Dependent
> public class ThreadLauncher {
> @Resource
> private ManagedThreadFactory threadFactory;
> @Inject
> private AppScopedBean bean;
>
> void start(@Observes @Initialized(ApplicationScoped.class) Object event) {
> System.out.println("starting threads");
> for (int i = 0; i < 5; i++) {
> threadFactory.newThread(new SendRunnable()).start();
> }
> System.out.println("start finished");
> }
>
> private class SendRunnable implements Runnable {
> public void run() {
> System.out.println("starting to send");
> for (int i = 0; i < 100; i++) {
> bean.sendMessage();
> }
> System.out.println("done sending");
> }
>
> }
>
> }
> {code}
> If you deploy and run the above code, you will see a lot of this:
> {quote}
> 2014-05-12 16:46:02,936 WARN [org.hornetq.core.client] (EE-ManagedThreadFactory-default-Thread-4) HQ212051: Invalid concurrent session usage. Sessions are not supposed to be used by more than one thread concurrently.: java.lang.Exception: trace
> {quote}
> That should not be happening if the JMSContext is really @TransactionScoped. The problem appears to be in org.jboss.as.messaging.deployment.JMSContextProducer, specifically the JMSContextWrapper.getDelegate() method. If two threads call it at the same time, the first will create a delegate but the second will receive the same delegate as the first, because the delegate doesn't get nulled until the transaction in the first thread completes.
> This means that both threads are using the same session at the same time, which is not allowed. I don't know how HornetQ detects concurrent use, but depending on how that works, it's also possible that messages will end up being part of the wrong transaction.
> A workaround is to inject Instance<JMSContext> instead of JMSContext directly (the two commented out lines of code). Since the JMSContext producer is @Dependent, each Instance.get() call will return a new instance, and only one thread will ever use any given instance.
--
This message was sent by Atlassian JIRA
(v6.2.6#6264)
More information about the jboss-jira
mailing list