使用mq-jms-spring-boot-starter连接IBM MQ的JNDI配置问题
使用mq-jms-spring-boot-starter实现IBM MQ JMS连接的配置问题
依赖信息
<dependency> <groupId>com.ibm.mq</groupId> <artifactId>mq-jms-spring-boot-starter</artifactId> <version>3.0.6</version> </dependency>
问题描述
- 初始连接异常:尝试通过JNDI连接远程IBM MQ时,触发连接拒绝错误,提示无法连接到
localhost(1414),但实际目标主机为x.x.x.x:1423。 - 队列识别异常:添加自定义
JmsConfig配置类指定正确参数后,应用启动无报错,但发送消息时提示队列名称未知(错误码MQRC_UNKNOWN_OBJECT_NAME),同时无法注册连接工厂java:/jms/queueProlog。
相关代码与配置
JMSService业务代码
@Slf4j @Service public class JMSService { static final String MESSAGE_FORMAT_MQSTR = "MQSTR"; private String destinationPromoJndiName = "jms/promoQueue"; @Autowired private JmsTemplate jmsTemplate; /** * 向Promo队列发送消息包 */ public void sendPromoPacket(final byte[] paquet) throws TechnicalException { try { log.info("send message to '{}'", this.destinationPromoJndiName); jmsTemplate.convertAndSend(this.destinationPromoJndiName, paquet); } catch (JmsException e) { e.printStackTrace(); throw new TechnicalException("error sending promo packet .."); } } }
目标MQ参数
# 连接工厂配置 jndi-queue-factory: jms/prologQF hostName: x.x.x.x port: 1423 prologQF_channel: QMX0.SVRC.APPPROMO prologQF_queueManager: QMX0 queueProxy_targetClient: MQJMS_CLIENT_NONJMS_MQ queueProxy_ccsid: 819 promoQueue_baseQueueName: APP.PROMO
错误日志
2024-04-16T10:31:20.862Z INFO 1 --- [tpmc1000] [nio-8080-exec-1] c.package.fr.app.storage.JMSService : send message to 'jms/queuePromo org.springframework.jms.InvalidDestinationException: JMSWMQ2008: Failed to open MQ queue 'jms/queuePrologPromo'.; nested exception is com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2085' ('MQRC_UNKNOWN_OBJECT_NAME'). ...
解决方案
1. 优先使用starter原生配置
mq-jms-spring-boot-starter提供了自动配置能力,无需手动编写JmsConfig,直接在application.yml中配置官方标准属性即可覆盖默认的localhost连接:
ibm.mq: queue-manager: QMX0 host: x.x.x.x port: 1423 channel: QMX0.SVRC.APPPROMO ccsid: 819 # 若MQ开启认证,补充以下配置 # user: your-mq-username # password: your-mq-password
2. 规范JNDI模式配置
若必须使用JNDI绑定,需在配置中明确声明连接工厂和队列的JNDI映射:
spring: jms: jndi-name: java:/jms/prologQF # 指定默认JmsTemplate使用的连接工厂JNDI名 ibm.mq.jndi: connection-factory: jms/prologQF: queueManager: QMX0 hostName: x.x.x.x port: 1423 channel: QMX0.SVRC.APPPROMO ccsid: 819 transportType: CLIENT queue: jms/promoQueue: baseQueueName: APP.PROMO targetClient: MQJMS_CLIENT_NONJMS_MQ
3. 修正JmsTemplate目标指向
- 若使用JNDI,确保
destinationPromoJndiName与配置中声明的队列JNDI名完全一致(当前代码中为jms/promoQueue,需与配置映射匹配)。 - 若无需JNDI,可直接使用MQ服务器上的物理队列名,跳过JNDI查找:
jmsTemplate.convertAndSend("APP.PROMO", paquet);
4. 验证队列权限与存在性
- 确认远程MQ服务器上存在
APP.PROMO物理队列。 - 检查当前连接用户拥有该队列的
PUT权限(发送消息需此权限)。
5. 消除配置冲突
删除自定义的JmsConfig类,避免与starter自动生成的连接工厂、JmsTemplate bean冲突,确保starter的自动配置逻辑正常生效。
内容的提问来源于stack exchange,提问作者Smaillns
相关产品推荐
相关产品推荐

