Spring Boot 3.2.0 JMS单元测试:Embedded ActiveMQ连接及消息属性问题
问题分析与解决方案
错误原因
Spring Boot 3.x 基于 Jakarta EE 9+,所有原Java EE API的包路径从javax.*迁移到了jakarta.*。你遇到的NoClassDefFoundError: javax/jms/JMSException,是因为类路径中缺少适配Jakarta环境的JMS API,同时测试代码混合了JUnit 4和JUnit 5的注解,进一步加剧了依赖冲突问题。
分步解决方案
1. 修正依赖配置
移除直接引入的ActiveMQ独立包,改用Spring Boot官方的ActiveMQ Starter,它会自动适配Spring Boot 3的Jakarta环境并管理依赖版本:
// 移除原有activemq-broker、activemq-all,替换为starter implementation 'org.springframework.boot:spring-boot-starter-activemq' // 保留activemq-junit,让Spring Boot管理版本 testImplementation 'org.apache.activemq.tooling:activemq-junit' // 其他测试依赖保持不变 testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.1' testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.9.1' testImplementation 'org.mockito:mockito-junit-jupiter:4.8.1' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.cloud:spring-cloud-starter-contract-stub-runner:4.1.0' testImplementation 'org.mockito:mockito-core:5.8.0' testImplementation 'org.testcontainers:testcontainers:1.19.3' testImplementation 'org.testcontainers:junit-jupiter:1.16.3' runtimeOnly 'com.h2database:h2' annotationProcessor 'org.projectlombok:lombok'
2. 修复测试类的JUnit版本冲突
你当前混合使用了JUnit 4的@RunWith、@ClassRule和JUnit 5的注解,需要统一为JUnit 5的写法:
import org.apache.activemq.junit.EmbeddedActiveMQBroker; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest public class JmsMessageListeningAndSendingTest extends IntegrationTestBase { // 替换JUnit 4的@ClassRule为JUnit 5的@RegisterExtension @RegisterExtension public static final EmbeddedActiveMQBroker embeddedBroker = new EmbeddedActiveMQBroker(); @Autowired private JmsMessageSender jmsMessageSender; @MockBean private JmsMessageListener jmsMessageListener; @Test void testSendAndReceiveWithProperty() throws InterruptedException { // 测试逻辑见下文示例 } }
3. 修正配置文件前缀
你的application.yml中缺少spring.前缀,导致ActiveMQ配置无法生效:
spring: activemq: broker-url: tcp://localhost:61616 close-timeout: 15 packages: trusted: com.broker.activemq.entities,java.lang password: admin user: admin in-memory: true pool: enabled: false
消息收发与属性处理示例
消息发送者(带属性设置)
import jakarta.jms.JMSException; import jakarta.jms.Message; import jakarta.jms.Session; import org.springframework.jms.core.JmsTemplate; import org.springframework.jms.core.MessageCreator; import org.springframework.stereotype.Component; @Component public class JmsMessageSender { private final JmsTemplate jmsTemplate; public JmsMessageSender(JmsTemplate jmsTemplate) { this.jmsTemplate = jmsTemplate; } public void sendMessageWithProperty(String destination, String content, String propKey, String propValue) { jmsTemplate.send(destination, session -> { Message message = session.createTextMessage(content); message.setStringProperty(propKey, propValue); return message; }); } }
消息监听器(提取属性)
import jakarta.jms.JMSException; import jakarta.jms.Message; import jakarta.jms.TextMessage; import org.springframework.jms.annotation.JmsListener; import org.springframework.stereotype.Component; @Component public class JmsMessageListener { @JmsListener(destination = "test-queue") public void handleMessage(Message message) throws JMSException { if (message instanceof TextMessage textMessage) { String content = textMessage.getText(); String customProp = message.getStringProperty("custom-tag"); // 业务处理逻辑 System.out.println("收到消息内容:" + content); System.out.println("自定义属性值:" + customProp); } } }
测试方法示例
@Test void testSendAndReceiveWithProperty() throws InterruptedException { String destination = "test-queue"; String content = "测试消息内容"; String propKey = "custom-tag"; String propValue = "activemq-test"; // 发送带属性的消息 jmsMessageSender.sendMessageWithProperty(destination, content, propKey, propValue); // 等待消息被处理(根据实际情况调整等待时长) Thread.sleep(1000); // 用Mockito验证监听器是否收到消息(可选) // verify(jmsMessageListener).handleMessage(any(Message.class)); }
内容的提问来源于stack exchange,提问作者user23114985
相关产品推荐
相关产品推荐

