[jboss-jira] [JBoss JIRA] (WFLY-9529) Using injected JMS in a background task/thread leads to NameNotFoundException: java:comp/TransactionSynchronizationRegistry

Peter Schulz (Jira) issues at jboss.org
Wed Feb 13 05:55:00 EST 2019


    [ https://issues.jboss.org/browse/WFLY-9529?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13694802#comment-13694802 ] 

Peter Schulz commented on WFLY-9529:
------------------------------------

Hi,

I just ran into the same issue and started digging deeper:

The bean which gets {{JMSContext}} injected *must be an EJB*, since the "missing" component {{java:comp/TransactionSynchronizationRegistry}} is only known inside the EJB wildfly-module.

{code:java}
import javax.annotation.Resource;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.jms.BytesMessage;
import javax.jms.CompletionListener;
import javax.jms.DeliveryMode;
import javax.jms.JMSConnectionFactory;
import javax.jms.JMSContext;
import javax.jms.JMSException;
import javax.jms.JMSProducer;
import javax.jms.Message;
import javax.jms.Queue;

import org.slf4j.Logger;

/**
 * See https://nozaki.me/roller/kyle/entry/in-container-jms-consumer-producer
 */
@Stateless
@LocalBean
public class MessageProducer {

    @Inject
    private Logger logger;

    @Inject
    @JMSConnectionFactory("java:/ConnectionFactory")
    private JMSContext context;

    @Resource(name = "java:/jms/queue/requestQueue")
    private Queue queue;

    private CompletionListener completionListener = new CompletionListener() {

        @Override
        public void onCompletion(Message message) {
            logger.debug("delivered message");
        }

        @Override
        public void onException(Message message, Exception exception) {
            logger.warn("failed to deliver message", exception);
        }

    };

    public void enqueue(Request request) {
        try {
            createProducer().send(queue, convert(request));
        } catch (JMSException e) {
            logger.error("failed to create message/convert request " + request, e);
        }
    }

    private JMSProducer createProducer() {
        JMSProducer producer = context.createProducer();
        producer.setJMSCorrelationID("SEQUENTIAL_REQUEST");
        producer.setDeliveryMode(DeliveryMode.PERSISTENT);
        producer.setDisableMessageTimestamp(false);
        producer.setDisableMessageID(false);
        producer.setAsync(completionListener);
        producer.setTimeToLive(0);

        return producer;
    }

    private BytesMessage convert(Request request) throws JMSException {
        // ...
    }
}
{code}

> Using injected JMS in a background task/thread leads to NameNotFoundException: java:comp/TransactionSynchronizationRegistry
> ---------------------------------------------------------------------------------------------------------------------------
>
>                 Key: WFLY-9529
>                 URL: https://issues.jboss.org/browse/WFLY-9529
>             Project: WildFly
>          Issue Type: Bug
>          Components: CDI / Weld, JMS, Naming
>    Affects Versions: 14.0.1.Final, 10.1.0.Final, 11.0.0.Final, 12.0.0.Final, 13.0.0.Final
>         Environment: Running on Windows 10, Java 64-bit 1.8.0_131
>            Reporter: Scott Van Wart
>            Assignee: Eduardo Martins
>            Priority: Major
>              Labels: ActiveMQ, jms, transaction
>         Attachments: injected-jms.zip, injected-jms2.zip, wildfly-11-injected-jms.txt
>
>
> If I try to use an @Injected JMSContext while executing within a background task (ManagedExecutorService) or thread (ManagedThreadFactory), I get the attached stacktrace. I've experienced this a number of times with Wildfly 10.1.0, including messages sent in Infinispan's expiry task thread.
> My original workaround was to submit an additional task on a separate thread to send the message, then wait for it to complete.  That seemed unreliable (sometimes it would still produce NameNotFoundException).  I've resorted to creating my own JMSContext by using @Resource( lookup="java:/ConnectionFactory" ) and sending messages that way.  Both workarounds prevent the message sending logic from participating in any ongoing transactions.
> I'm also attaching a sample EAR project.  It can be built with Maven.  It creates a background task that waits 3 seconds and then tries to send a JMS message in a new transaction using an injected JMS context. I use the standalone-full.xml profile to run it.



--
This message was sent by Atlassian Jira
(v7.12.1#712002)


More information about the jboss-jira mailing list