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

使用ActiveMQ Artemis与OpenLiberty时JMS ConnectionFactory注入为空问题

问题根源与解决方案

你的核心问题是Jakarta EE 9.1与旧JMS API包的命名空间不匹配,以及server.xml缺少ActiveMQ Artemis集成特性,导致JNDI无法正确找到ConnectionFactory实例。

1. 替换JMS API包命名空间

Jakarta EE 9+将Java EE的API从javax.*迁移到jakarta.*,你的代码中混用了旧的javax.jms和新的jakarta.*注解,导致类型匹配失败。需要将所有JMS相关的导入替换为jakarta.jms:

修改JMSConfig类

package com.demo.rest;

import jakarta.annotation.Resource;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.jms.ConnectionFactory; // 替换javax.jms为jakarta.jms
import jakarta.jms.Queue;

@ApplicationScoped
public class JMSConfig {

    @Resource(lookup = "jms/ArtemisConnectionFactory")
    private ConnectionFactory connectionFactory;

    @Resource(lookup = "jms/ArtemisQueue")
    private Queue queue;

    public ConnectionFactory getConnectionFactory() {
        return connectionFactory;
    }

    public Queue getQueue() {
        return queue;
    }
}

修改MessageProducer类

package com.demo.rest;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.jms.Connection; // 替换javax.jms为jakarta.jms
import jakarta.jms.JMSException;
import jakarta.jms.MessageProducer;
import jakarta.jms.Session;
import jakarta.jms.TextMessage;

@ApplicationScoped
public class MessageProducer {

    @Inject
    private JMSConfig jmsConfig;

    public MessageProducer() {
    }

    public void sendMessage(String text) throws JMSException {
        try (Connection connection = jmsConfig.getConnectionFactory().createConnection();
             Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
             MessageProducer producer = session.createProducer(jmsConfig.getQueue())) {

            TextMessage message = session.createTextMessage(text);
            producer.send(message);
        }
    }
}

修改MessageConsumerMDB类

注意要修改destinationType的属性值为jakarta.jms.Queue,同时替换JMS API包:

package com.demo.rest;

import jakarta.ejb.ActivationConfigProperty;
import jakarta.ejb.MessageDriven;
import jakarta.jms.JMSException;
import jakarta.jms.Message;
import jakarta.jms.MessageListener;
import jakarta.jms.TextMessage;

import java.util.logging.Level;
import java.util.logging.Logger;

@MessageDriven(activationConfig = {
        @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "jakarta.jms.Queue"), // 替换javax.jms.Queue
        @ActivationConfigProperty(propertyName = "destination", propertyValue = "jms/ArtemisQueue"),
        @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge")
})
public class MessageConsumerMDB implements MessageListener {

    private static final Logger LOGGER = Logger.getLogger(MessageConsumerMDB.class.getName());

    @Override
    public void onMessage(Message message) {
        if (message instanceof TextMessage) {
            try {
                String content = ((TextMessage) message).getText();
                LOGGER.log(Level.INFO, "Received message: " + content);
            } catch (JMSException e) {
                LOGGER.log(Level.SEVERE, "Error reading message", e);
            }
        } else {
            LOGGER.log(Level.WARNING, "Received non-text message");
        }
    }
}

2. 完善server.xml的特性配置

默认的jakartaee-9.1特性并不包含ActiveMQ Artemis的集成组件,需要添加messaging-activemq特性到featureManager中,确保服务器能识别Artemis的JMS配置:

<?xml version="1.0" encoding="UTF-8"?>
<server description="new server">

    <featureManager>
        <feature>jakartaee-9.1</feature>
        <feature>messaging-activemq</feature> <!-- 添加此特性 -->
    </featureManager>

    <jmsConnectionFactory jndiName="jms/ArtemisConnectionFactory">
        <properties.activemq
                brokerURL="tcp://localhost:61616"
                userName="admin"
                password="admin"/>
    </jmsConnectionFactory>

    <jmsQueue id="jms/ArtemisQueue" jndiName="jms/ArtemisQueue">
        <properties.activemq queueName="Test_Queue"/>
    </jmsQueue>

    <basicRegistry id="basic" realm="BasicRealm"/>

    <httpEndpoint id="defaultHttpEndpoint"
                  httpPort="9080"
                  httpsPort="9443" />

    <applicationManager autoExpand="true"/>

    <ssl id="defaultSSLConfig" trustDefaultCerts="true" />
</server>

3. 额外检查点

  • 确保ActiveMQ Artemis broker已在tcp://localhost:61616运行,并且配置的admin/admin用户名密码有效。
  • 验证应用部署时服务器日志中没有JNDI绑定失败的提示,确认jms/ArtemisConnectionFactory和jms/ArtemisQueue已成功注册。
  • 检查项目依赖是否使用了Jakarta EE 9.1版本的JMS API,避免混合引入javax.jms和jakarta.jms的依赖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 11:35:24