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
相关产品推荐
相关产品推荐

