Java17升级后Cached JMS Session对象打印为null的技术问询
问题分析与解决方案
问题背景
我们的Java后端应用部署在Tomcat中,基于Atomikos实现分布式两阶段提交事务,通过Spring JMS操作IBM MQ、Oracle DB做数据持久化。在从Java11→Java17、Tomcat9→10.1.x(Jakarta API)的升级过程中,出现以下异常:
- 原环境(Java11 + com.ibm.mq.allclient-7.5.0.0 + spring-jms-5.3.x + Atomikos-5.0.8):JmsTemplate日志正常打印缓存会话:
Executing callback on JMS Session: Cached JMS Session: com.ibm.mq.jms.MQXAQueueSession@39f839d6 - 升级后环境(Java17 + com.ibm.mq.jakarta.client-9.4.0.0 + spring-jms-6.1.5 + Atomikos-6.0.0):日志出现
Executing callback on JMS Session: Cached JMS Session: Cached JMS Session: null,追踪发现CachingConnectionFactory返回的缓存Session为null - 进一步验证:Java11环境下,com.ibm.mq.allclient升级至9.2.3.0前正常,9.2.4.0开始出现该问题;MQ客户端日志显示新版本中
createXAQueueSession()和createXASession()返回null
根本原因
- IBM MQ客户端XA会话实现变更:从9.2.4.0版本开始,IBM MQ调整了XA会话的创建逻辑,
createXAQueueSession()/createXASession()方法返回null,因为客户端默认采用Jakarta EE标准的XA资源获取方式,不再直接返回传统的MQXAQueueSession实例,而SpringCachingConnectionFactory的缓存逻辑仍依赖旧API的返回值,导致缓存的Session无法正确初始化。 - Spring JMS 6.x与MQ Jakarta客户端的适配差异:Spring JMS 6.x针对Jakarta API做了重构,但未完全适配IBM MQ 9.4.x的XA会话创建回调机制,导致缓存逻辑无法正确捕获有效的Session实例。
- Atomikos 6.0.0的XA资源注册逻辑变更:新版本Atomikos对Jakarta EE的XA资源处理流程做了调整,与IBM MQ新客户端的会话注册路径不匹配,使得会话未被正确纳入缓存管理。
解决方案
1. 调整Spring CachingConnectionFactory配置
禁用消费者缓存(或调整缓存策略),避免因XA会话创建逻辑变更导致的null缓存问题:
@Bean public CachingConnectionFactory cachingConnectionFactory(XAConnectionFactory xaConnectionFactory) { CachingConnectionFactory factory = new CachingConnectionFactory(xaConnectionFactory); factory.setCacheProducers(true); // 保留生产者缓存 factory.setCacheConsumers(false); // 禁用消费者缓存,规避null会话 factory.setSessionCacheSize(10); return factory; }
2. 强制IBM MQ客户端使用传统XA会话逻辑
通过系统属性或连接工厂配置,强制MQ客户端返回传统的XA会话实例:
- 添加JVM启动参数:
-Dcom.ibm.mq.jakarta.xa.useJakartaXA=false - 或在代码中配置连接工厂:
MQXAConnectionFactory mqXAConnectionFactory = new MQXAConnectionFactory(); mqXAConnectionFactory.setUseJakartaXA(false); // 强制使用旧XA会话创建逻辑
3. 降级IBM MQ客户端版本
若业务允许,暂时回退至com.ibm.mq.jakarta.client-9.2.3.0,该版本在Java17+Jakarta环境下仍能与Spring JMS 6.x、Atomikos 6.0.0保持兼容,可快速规避问题。
4. 升级Spring JMS至最新稳定版
Spring官方后续版本(如6.1.6及以上)可能修复了与IBM MQ 9.4.x的XA会话缓存适配问题,升级到最新版本可彻底解决该兼容缺陷。
内容的提问来源于stack exchange,提问作者Ravi Shankar
相关产品推荐
相关产品推荐

