You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Quarkus与Apache Camel、TIBCO EMS兼容问题及实现咨询

适配TIBCO EMS 8.4的Quarkus版本及Quarkus 3.x兼容方案

一、适配TIBCO EMS 8.4的Quarkus版本

TIBCO EMS 8.4仅提供基于javax.jms命名空间的客户端库,因此**Quarkus 2.x系列(推荐2.16.x LTS长期支持版本)**是直接适配的版本——Quarkus 2.x基于Jakarta EE 8兼容栈,底层仍使用javax命名空间,无需额外适配即可直接使用TIBCO EMS 8.4的ConnectionFactory。

二、在Quarkus 3.x中使用javax版ConnectionFactory的实现方案

Quarkus 3.x完全切换到Jakarta EE 9+的jakarta.jms命名空间,无法直接强制转换javax.jms.ConnectionFactory到jakarta.jms.ConnectionFactory,需通过包装类桥接+依赖调整来解决:

1. 调整pom.xml依赖

  • 移除冲突的javax依赖:
    • 删除javax.jms:javax.jms-api(Quarkus 3.x自带jakarta.jms:jakarta.jms-api)
    • 删除org.apache.camel:camel-jms(由camel-quarkus-jms提供适配Quarkus的Jakarta版本)
    • 将javax.inject:javax.inject替换为jakarta.inject:jakarta.inject-api
  • 保留核心依赖:
    <!-- Camel JMS Quarkus扩展 -->
    <dependency>
        <groupId>org.apache.camel.quarkus</groupId>
        <artifactId>camel-quarkus-jms</artifactId>
    </dependency>
    <!-- TIBCO EMS客户端 -->
    <dependency>
        <groupId>com.tibco.ems</groupId>
        <artifactId>tibjms</artifactId>
        <version>${tibco-ems.version}</version>
    </dependency>
    <!-- Jakarta Inject替代javax.inject -->
    <dependency>
        <groupId>jakarta.inject</groupId>
        <artifactId>jakarta.inject-api</artifactId>
        <scope>compile</scope>
    </dependency>
    

2. 编写javax到Jakarta的ConnectionFactory包装类

创建桥接类,将javax.jms.ConnectionFactory适配为jakarta.jms.ConnectionFactory(需覆盖业务用到的所有JMS接口方法):

import jakarta.jms.*;
import javax.jms.ConnectionFactory;

public class JavaxToJakartaConnectionFactoryWrapper implements jakarta.jms.ConnectionFactory {

    private final ConnectionFactory delegate;

    public JavaxToJakartaConnectionFactoryWrapper(ConnectionFactory delegate) {
        this.delegate = delegate;
    }

    @Override
    public Connection createConnection() throws JMSException {
        try {
            return new JavaxToJakartaConnectionWrapper(delegate.createConnection());
        } catch (javax.jms.JMSException e) {
            throw convertJmsException(e);
        }
    }

    @Override
    public Connection createConnection(String userName, String password) throws JMSException {
        try {
            return new JavaxToJakartaConnectionWrapper(delegate.createConnection(userName, password));
        } catch (javax.jms.JMSException e) {
            throw convertJmsException(e);
        }
    }

    @Override
    public JMSContext createContext() {
        try {
            return new JavaxToJakartaContextWrapper(delegate.createContext());
        } catch (javax.jms.JMSException e) {
            throw new jakarta.jms.JMSRuntimeException(e.getMessage(), e.getErrorCode(), e.getCause());
        }
    }

    // 实现JMSContext的其他重载方法、转换异常逻辑,此处省略
    // 同时需编写Connection、Session、Message等内部包装类,委托原javax实例并转换异常

    private jakarta.jms.JMSException convertJmsException(javax.jms.JMSException e) {
        jakarta.jms.JMSException jakartaEx = new jakarta.jms.JMSException(e.getMessage(), e.getErrorCode());
        jakartaEx.setLinkedException(e.getLinkedException());
        jakartaEx.initCause(e.getCause());
        return jakartaEx;
    }

    // 内部包装Connection类示例
    private static class JavaxToJakartaConnectionWrapper implements jakarta.jms.Connection {
        private final javax.jms.Connection delegate;

        public JavaxToJakartaConnectionWrapper(javax.jms.Connection delegate) {
            this.delegate = delegate;
        }

        @Override
        public Session createSession() throws JMSException {
            try {
                return new JavaxToJakartaSessionWrapper(delegate.createSession());
            } catch (javax.jms.JMSException e) {
                throw convertJmsException(e);
            }
        }

        // 实现Connection的其他方法,委托原实例并转换异常,此处省略

        private jakarta.jms.JMSException convertJmsException(javax.jms.JMSException e) {
            jakarta.jms.JMSException jakartaEx = new jakarta.jms.JMSException(e.getMessage(), e.getErrorCode());
            jakartaEx.setLinkedException(e.getLinkedException());
            jakartaEx.initCause(e.getCause());
            return jakartaEx;
        }
    }

    // 其余内部包装类(Session、JMSContext等)按需实现
}

3. 修改ConnectionFactory生产者代码

将原来返回javax.jms.ConnectionFactory的生产者,改为返回包装后的jakarta.jms.ConnectionFactory:

@Produces
@ApplicationScoped
public jakarta.jms.ConnectionFactory jmsConnectionFactory() throws NamingException {
    javax.jms.ConnectionFactory javaxCf = tibcoEmsConfiguration.jmsConnectionFactory();
    return new JavaxToJakartaConnectionFactoryWrapper(javaxCf);
}

4. 调整Camel路由配置

直接使用适配后的Jakarta ConnectionFactory,无需强制转换:

@Override
public void configure() throws Exception {
    getContext().addComponent("jms",
            JmsComponent.jmsComponentAutoAcknowledge(jmsConnectionFactory()));

    from("jms:queue:myQueue")
            .log("Received message in TIBCO EMS: ${body}")
            .to("rabbitmq://localhost:5672/myExchange?queue=rabbitQueue&autoDelete=false&durable=false");

    from("timer:myTimer?period=5000")
            .setBody(simple("Hello from Quarkus Camel 1"))
            .to("jms:queue:myQueue");
}

三、注意事项

  • 包装类需要覆盖业务中用到的所有JMS接口方法,避免出现未实现异常
  • Quarkus 3.x原生模式下,需注册TIBCO EMS相关类到镜像中,可添加配置:
    <properties>
        <quarkus.native.additional-build-args>--initialize-at-build-time=com.tibco.tibjms.TibjmsConnectionFactory</quarkus.native.additional-build-args>
    </properties>
    

内容的提问来源于stack exchange,提问作者user11734281

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 13:24:50