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

Spring Boot使用IBM MQ发送消息到Topic失败问题及解决

使用JmsTemplate通过IBM MQ发送消息到Topic时JMSCC1112错误的解决办法

问题场景

尝试通过JmsTemplate实现将消息发送到IBM MQ的Topic而非队列,配置运行后触发如下错误:

com.ibm.msg.client.jakarta.jms.DetailedIllegalStateException: JMSCC1112: The operation for a domain specific object was not valid. The operation 'createTopic' is not valid for type 'QueueSession'.
A JMS application attempted to perform an operation on domain specific object, but the operation is valid only for the other messaging domain.

原配置与代码

1. MQ配置类

@Configuration
@EnableJms
public class MQConfiguration {

    @Value("${notification.topic.name}")
    String notificationTopicName;

    @Bean
    @ConfigurationProperties(prefix = "jms-mq.notification")
    public MQConfigurationProperties mqConfigurationProperties() {
        return new MQConfigurationProperties();
    }

    @Bean
    public MQQueueConnectionFactory mqQueueConnectionFactory() {
        MQConnectionFactoryFactory mqConnectionFactoryFactory = new MQConnectionFactoryFactory(mqConfigurationProperties(), null);
        MQQueueConnectionFactory mqQueueConnectionFactory = mqConnectionFactoryFactory.createConnectionFactory(MQQueueConnectionFactory.class);
       return mqQueueConnectionFactory;
    }

    @Bean
    public JmsListenerContainerFactory<?> jmsListenerContainerFactory(DefaultJmsListenerContainerFactoryConfigurer configurer){
        DefaultJmsListenerContainerFactory defaultJmsListenerContainerFactory=new DefaultJmsListenerContainerFactory();
        defaultJmsListenerContainerFactory.setConnectionFactory(mqQueueConnectionFactory());
        defaultJmsListenerContainerFactory.setPubSubDomain(true);
        configurer.configure(defaultJmsListenerContainerFactory,mqQueueConnectionFactory());
        defaultJmsListenerContainerFactory.setClientId("producer");
        return defaultJmsListenerContainerFactory;
    }

    @Bean
    public JmsTemplate jmsTemplate(){
        JmsTemplate jmsTemplate=new JmsTemplate();
        jmsTemplate.setPubSubDomain(true);
        jmsTemplate.setDefaultDestinationName(notificationTopicName);
        jmsTemplate.setConnectionFactory(mqQueueConnectionFactory());
        return jmsTemplate;
    }
}

2. application.yaml配置

jms-mq:
  notification:
    conn-name: edb2pre2.momentum.co.za(1414)
    queueManager: edb2pre1.que.mgr
    channel: TCP.CLT.CHL

3. 消息发送代码

try {
            String jsonMessage= objectMapper.writeValueAsString(notification);
            jmsTemplate.convertAndSend(notificationTopicName,jsonMessage);
        } catch (JsonProcessingException | JmsException e) {
            throw new RuntimeException(e);
        }

错误原因

MQQueueConnectionFactory是IBM MQ针对点对点(PTP)队列域设计的专用连接工厂,它创建的Session是QueueSession,仅支持队列相关操作,无法执行createTopic这类发布订阅域的操作。即便在JmsTemplate和Listener容器中设置了setPubSubDomain(true),底层连接工厂的域限制依然会导致操作无效。

解决方法

将专用的MQQueueConnectionFactory替换为通用的MQConnectionFactory,它同时支持点对点和发布订阅两个域的操作,能够适配Topic的创建与消息发送需求。

修改后的连接工厂创建代码如下:

@Bean
public MQConnectionFactory mqConnectionFactory() {
    MQConnectionFactoryFactory mqConnectionFactoryFactory = new MQConnectionFactoryFactory(mqConfigurationProperties(), null);
    MQConnectionFactory mqConnectionFactory = mqConnectionFactoryFactory.createConnectionFactory(MQConnectionFactory.class);
    return mqConnectionFactory;
}

同时需要更新配置类中所有引用该Bean的地方(jmsListenerContainerFactory和jmsTemplate的setConnectionFactory方法参数),确保使用新的mqConnectionFactoryBean。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 10:28:24