Spring JMS发送消息报错:X-Correlation-Id不是合法Java标识符
问题解决:JMS属性名'x-correlation-id'不是合法Java标识符
问题场景
使用Spring JmsTemplate发送JMS消息,代码如下:
jmsTemplate.convertAndSend(topicName, WebsocketMessage("<message content>"))
配置了MappingJackson2MessageConverter作为消息转换器,同时通过Micrometer追踪配置了名为X-Correlation-Id的baggage字段,发送时抛出错误:
jakarta.jms.JMSRuntimeException: AMQ139012: The property name 'x-correlation-id' is not a valid java identifier. at org.apache.activemq.artemis.jms.client.ActiveMQMessage.checkProperty(ActiveMQMessage.java:911) at org.apache.activemq.artemis.jms.client.ActiveMQMessage.setStringProperty(ActiveMQMessage.java:669) at io.micrometer.jakarta9.instrument.jms.JmsPublishObservationContext.lambda$new$0(JmsPublishObservationContext.java:40) at io.micrometer.tracing.handler.PropagatingSenderTracingObservationHandler.lambda$onStart$0(PropagatingSenderTracingObservationHandler.java:60) at brave.baggage.BaggagePropagation$BaggageInjector.inject(BaggagePropagation.java:342) at io.micrometer.tracing.brave.bridge.BravePropagator.inject(BravePropagator.java:53) at io.micrometer.tracing.handler.PropagatingSenderTracingObservationHandler.onStart(PropagatingSenderTracingObservationHandler.java:59) at io.micrometer.tracing.handler.PropagatingSenderTracingObservationHandler.onStart(PropagatingSenderTracingObservationHandler.java:35) at io.micrometer.observation.ObservationHandler$FirstMatchingCompositeObservationHandler.onStart(ObservationHandler.java:149) at io.micrometer.observation.SimpleObservation.notifyOnObservationStarted(SimpleObservation.java:214) at io.micrometer.observation.SimpleObservation.start(SimpleObservation.java:161) at io.micrometer.jakarta9.instrument.jms.MessageProducerInvocationHandler.invoke(MessageProducerInvocationHandler.java:57) at jdk.proxy2/jdk.proxy2.$Proxy258.send(Unknown Source) at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:657) at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:634) at org.springframework.jms.core.JmsTemplate.lambda$send$3(JmsTemplate.java:612) at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:530) at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:610) at org.springframework.jms.core.JmsTemplate.convertAndSend(JmsTemplate.java:687)
原因分析
JMS规范要求消息属性名必须是合法的Java标识符:
- 只能包含字母、数字、下划线(
_) - 首字符必须是字母或下划线
Micrometer的追踪组件会将配置的baggage字段名直接作为JMS消息属性注入,而x-correlation-id包含连字符(-),不符合ActiveMQ Artemis的属性名校验规则,因此触发错误。
解决方案
方案1:修改Baggage字段名为合法Java标识符
这是最直接且符合规范的方案,将X-Correlation-Id改为符合Java标识符规则的名称,比如xCorrelationId或X_CORRELATION_ID。
代码配置示例:
@Bean public BaggageField xCorrelationId() { return BaggageField.create("xCorrelationId"); }
配置文件示例(application.properties):
management.tracing.baggage.fields=xCorrelationId
方案2:自定义属性注入逻辑(保留原字段名)
如果必须保留X-Correlation-Id的命名格式(比如跨系统约定),可以自定义Micrometer的Propagator,在注入JMS属性时将连字符替换为下划线,转换为合法格式:
@Bean public Propagator propagator(BaggageField xCorrelationId) { return new BravePropagator(BaggagePropagation.newBuilder(B3Propagation.FACTORY) .add(xCorrelationId) .injectFormatter((key, value, carrier) -> { // 将连字符替换为下划线,生成合法的JMS属性名 String validKey = key.replace("-", "_"); ((JmsMessageCarrier) carrier).setStringProperty(validKey, value); }) .build()); }
方案3:关闭ActiveMQ Artemis的属性名校验(不推荐)
可以通过Artemis的配置关闭属性名合法性校验,但这违反JMS规范,可能导致兼容性问题,仅建议测试环境临时使用:
在broker.xml中添加或修改配置:
<core> ... <jms-property-check-validity>false</jms-property-check-validity> ... </core>
内容的提问来源于stack exchange,提问作者Shannu Vaddi
相关产品推荐
相关产品推荐

