独立Jar运行时MQQueueConnectionFactory实例化失败问题
解决独立Jar运行时实例化MQQueueConnectionFactory失败问题
问题场景
程序在IntelliJ中运行正常,但打包为独立Jar执行时,实例化MQQueueConnectionFactory抛出空指针异常,导致启动失败。
相关代码
CfQueueSender queueSender = new CfQueueSender("send", MQConfigFile, jksFile); queueSender.setHostName(hostName); queueSender.setPortNumber(portNumber); queueSender.setQueueManager(queueManager); queueSender.setChannelName(channelName); queueSender.setChannelIdentifier(channelIdentifier); queueSender.sendNewAmendmentCancel(BEMRTMessage, numberOfMessagesToPush); public void sendNewAmendmentCancel(String message, int numberOfMessagesToPush) throws Exception { MQQueueConnectionFactory cf = new MQQueueConnectionFactory(); ...... }
运行时错误日志
Exception in thread "main" java.lang.NullPointerException at com.ibm.msg.client.jms.internal.JmsFactoryFactoryImpl.getInstance(JmsFactoryFactoryImpl.java:170) at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl.setProviderFactory(JmsConnectionFactoryImpl.java:167) at com.ibm.mq.jms.MQConnectionFactory.<init>(MQConnectionFactory.java:271) at com.ibm.mq.jms.MQQueueConnectionFactory.<init>(MQQueueConnectionFactory.java:72) at Runner.CfQueueSender.sendNewAmendmentCancel(CfQueueSender.java:42) at Runner.SMSListenerUtility.main(SMSListenerUtility.java:22)
IBM跟踪信息
WorkQueueMananger Contents -------------------------- | Maintain ThreadPool size :- false | Maximum ThreadPool size :- -1 | ThreadPool inactive timeout :- 0 | unavailable - :- com.ibm.msg.client.commonservices.CSIException: JMSCS0002 Stack trace ----------- Stack trace to show the location of the FFST call | FFST Location :- java.lang.Exception | at com.ibm.msg.client.commonservices.trace.Trace.getCurrentPosition(Trace.java:2146) | at com.ibm.msg.client.commonservices.trace.Trace.createFFSTString(Trace.java:2056) | at com.ibm.msg.client.commonservices.trace.Trace.ffstInternal(Trace.java:1938) | at com.ibm.msg.client.commonservices.trace.Trace.ffst(Trace.java:1739) | at com.ibm.msg.client.commonservices.nls.PINLSServices.createException(PINLSServices.java:112) | at com.ibm.msg.client.commonservices.nls.NLSServices.createException(NLSServices.java:226) | at com.ibm.msg.client.jms.internal.JmsErrorUtils.createException(JmsErrorUtils.java:126) | at com.ibm.msg.client.jms.internal.JmsFactoryFactoryImpl.getInstance(JmsFactoryFactoryImpl.java:168) | at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl.setProviderFactory(JmsConnectionFactoryImpl.java:167) | at com.ibm.mq.jms.MQConnectionFactory.<init>(MQConnectionFactory.java:271) | at com.ibm.mq.jms.MQQueueConnectionFactory.<init>(MQQueueConnectionFactory.java:72) | at Runner.CfQueueSender.sendNewAmendmentCancel(CfQueueSender.java:42) | at Runner.SMSListenerUtility.main(SMSListenerUtility.java:22) |
IBM MQ依赖Jar

解决方案
1. 修复打包方式,确保SPI配置文件被正确合并
问题核心是IBM MQ的SPI配置文件未被包含到独立Jar中:IntelliJ运行时会自动加载classpath下的所有资源,但普通Jar打包会丢失META-INF/services下的SPI配置,导致JmsFactoryFactory无法找到实现类,触发空指针。
推荐使用Fat Jar打包工具,合并所有依赖类和配置文件:
- Maven使用
maven-shade-plugin,需配置合并SPI文件,避免覆盖:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.3.0</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <!-- 合并SPI服务配置文件 --> <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/> <!-- 指定主类 --> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>Runner.SMSListenerUtility</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin>
- Gradle使用
shadowJar插件,默认会处理SPI文件合并,只需指定主类即可。
2. 确认依赖完整性
- 优先使用
com.ibm.mq:com.ibm.mq.allclient依赖,它包含所有MQ客户端核心组件,避免手动引入Jar遗漏。 - 若手动引入Jar,确保包含
com.ibm.mq.jar、com.ibm.mq.jms.jar、com.ibm.msg.client.jms.jar、com.ibm.msg.client.commonservices.jar等核心Jar,且版本完全一致。
3. 排查类加载冲突
运行独立Jar时,避免通过-cp参数指定其他可能导致类冲突的Jar,确保classpath中只有打包好的Fat Jar。
4. 解读JMSCS0002错误
JMSCS0002表示无法加载服务提供者配置,这直接印证了SPI配置文件缺失的问题,通过Fat Jar打包合并SPI文件即可解决该错误。
内容的提问来源于stack exchange,提问作者KOTIOS
相关产品推荐
相关产品推荐

