java - 在事务中将消息发布到远程 TIBCO JMS 提供程序

标签 java jakarta-ee transactions jta

在本例中,我有以下代码将消息发送到远程 jms 提供程序(Tibco),我正在寻找一种解决方案,将发送代码放入 Bean 管理的事务或用户事务中,但不确定如何执行此操作。

import java.util.Hashtable;

import javax.annotation.Resource;
import javax.inject.Singleton;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.transaction.Transactional;
import javax.transaction.Transactional.TxType;
import javax.transaction.UserTransaction;

@Singleton
public class ServiceLayer implements IServiceLayer{

    public final static String JNDI_FACTORY = "com.tibco.tibjms.naming.TibjmsInitialContextFactory";
    public final static String PROVIDER_URL = "tcp://serverurl:7225";

    public final static String JMS_FACTORY = "XAQueueConnectionFactory";
    public final static String QUEUE = "Queue";

    @Resource 
    public UserTransaction utx;

    public void sendMessage(String message) throws Exception {
        Hashtable env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
        env.put(Context.PROVIDER_URL, PROVIDER_URL);
        for (int i = 0; i < 1; i++) {
            // Define queue
            QueueSender qsender = null;
            QueueSession qsession = null;
            QueueConnection qcon = null;
            try {
                utx.begin();
                InitialContext ctx = new InitialContext(env);

                QueueConnectionFactory qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);
                qcon = qconFactory.createQueueConnection();

                qsession = qcon.createQueueSession(true, -1);
                Queue queue = (Queue) ctx.lookup(QUEUE);

                TextMessage msg = qsession.createTextMessage();
                msg.setText(message);

                qsender = qsession.createSender(queue);
                qsender.send(msg);
                System.out.println("sleep 5 secs.." + message.toString());
                Thread.sleep(5000);

                System.out.println("Message [" + msg.getText() + "] sent to Queue: " + QUEUE);
//              qsession.commit();
                utx.commit();
            } catch (Exception ex) {
                ex.printStackTrace();
            } finally {
                if (qsender != null)
                    qsender.close();
                if (qsession != null)
                    qsession.close();
                if (qcon != null)
                    qcon.close();
            }
        }
    }
}

技术堆栈/背景:

Wildfly、CDI、Tibco ems 8.2 JMS 提供程序、Java8、使用 Standalone-full.xml,添加了 genericra.rar 资源适配器文件以使用消息并且可以正常工作。用于消费消息的消息驱动 Bean。

最佳答案

我找到了解决方案。幸运的是我已经在 Wildfly 上安装了 genericra.rar。所以,这对我来说是小菜一碟。 GenericJmsXA jndi 名称位于资源适配器设置中。

@Singleton
@Transactional(value = TxType.REQUIRES_NEW)
public class ServiceLayer implements IServiceLayer {

    @Resource(mappedName="GenericJmsXA")
    public ConnectionFactory queueFactory; 

    private String QUEUE = "Queue";


    public void sendMessage(String message) throws Exception {

        MessageProducer qsender = null;

        Session qsession = null;

        Connection qcon = null;

        try{    
            qcon = this.queueFactory.createConnection();    
            qsession = qcon.createSession(true, QueueSession.AUTO_ACKNOWLEDGE);    
            Queue q = qsession.createQueue(QUEUE);    
            qsender = qsession.createProducer(q);    
            TextMessage tm = qsession.createTextMessage(message);    
            System.out.println("Before sending to Queue: Waiting for 5 seconds. " + QUEUE);    
            qsender.send(tm);    
            Thread.sleep(5000);    
            System.out.println("Message [" + tm.getText() + "] sent to Queue: " + QUEUE);
        }catch(Exception e){

            System.out.println("Exception : "+e.getMessage());

            e.printStackTrace();

        }

}

Wildfly 资源适配器设置。这里的大多数步骤都是准确的:https://github.com/jms-ra/generic-jms-ra只要跟随他们,你就能够让它发挥作用。

<subsystem xmlns="urn:jboss:domain:resource-adapters:4.0">  
    <resource-adapters>  
        <resource-adapter>  
            <archive>  
                generic-jms-ra.rar  
            </archive>  
            <transaction-support>NoTransaction</transaction-support>  
            <connection-definitions>  
                <connection-definition class-name="org.jboss.resource.adapter.jms.JmsManagedConnectionFactory" jndi-name="java:/GenericJmsXA" enabled="true" use-java-context="true" pool-name="GenericJmsXA" use-ccm="true">  
                    <config-property name="JndiParameters">  
                        java.naming.factory.initial=com.tibco.tibjms.naming.TibjmsInitialContextFactory;java.naming.provider.url=tcp://serverurl:7225  
                    </config-property>  
                    <config-property name="ConnectionFactory">  
                        XAQueueConnectionFactory  
                    </config-property>  
                    <pool>  
                        <min-pool-size>0</min-pool-size>  
                        <max-pool-size>10</max-pool-size>  
                        <prefill>false</prefill>  
                        <use-strict-min>false</use-strict-min>  
                        <flush-strategy>FailingConnectionOnly</flush-strategy>  
                    </pool>  
                    <security>  
                        <application></application>  
                    </security>  
                </connection-definition>  
            </connection-definitions>  
        </resource-adapter>  
    </resource-adapters>  
</subsystem> 

感谢贾斯汀帮助我解决这个问题:https://developer.jboss.org/thread/274204

关于java - 在事务中将消息发布到远程 TIBCO JMS 提供程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42534808/

相关文章:

java - 如何在不使用 IDE 的情况下调试 Java 程序?

java - 当 Java 中出现堆溢出时,我如何知道什么正在使用内存?

java - JSF:在一个下拉列表中选择值会启用另一个下拉列表

java - 在android中使用共享首选项存储用户名

java - dataTable sortBy 函数不起作用(primefaces)

java - 如何使用不同的输入对象映射到同一业务对象?

java - Spring hibernate "You cannot commit during a managed transaction!"

没有 TransactionScope 的 .Net Core 事务装饰器

java - 类文件 javax/transaction/SystemException 中非 native 或抽象方法中缺少代码属性

java - 最大重复字符数和数量