我对来自JMSMessageProperties类的“timestamp
”头有问题,或者在我看来是这样,它导致了以下错误
[WARN ] [2022-04-06 14:49:03,758] [voryouDuplicateCheck.container-1] DefaultJmsHeaderMapper - failed to map Message header 'timestamp' to JMS property
javax.jms.MessageNotWriteableException: Message properties are read-only
at org.apache.activemq.command.ActiveMQMessage.checkReadOnlyProperties(ActiveMQMessage.java:740) ~[activemq-client-5.15.0.jar:5.15.0]
at org.apache.activemq.command.ActiveMQMessage.setObjectProperty(ActiveMQMessage.java:494) ~[activemq-client-5.15.0.jar:5.15.0]
at org.apache.activemq.command.ActiveMQMessage.setObjectProperty(ActiveMQMessage.java:488) ~[activemq-client-5.15.0.jar:5.15.0]
at org.springframework.integration.jms.DefaultJmsHeaderMapper.fromHeaders(DefaultJmsHeaderMapper.java:152) [spring-integration-jms-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.integration.jms.DefaultJmsHeaderMapper.fromHeaders(DefaultJmsHeaderMapper.java:57) [spring-integration-jms-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.integration.jms.JmsSendingMessageHandler$HeaderMappingMessagePostProcessor.postProcessMessage(JmsSendingMessageHandler.java:167) [spring-integration-jms-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.jms.core.JmsTemplate$7.createMessage(JmsTemplate.java:686) [spring-jms-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:593) [spring-jms-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.jms.core.JmsTemplate$3.doInJms(JmsTemplate.java:562) [spring-jms-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:484) [spring-jms-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:559) [spring-jms-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.jms.core.JmsTemplate.convertAndSend(JmsTemplate.java:682) [spring-jms-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.integration.jms.JmsSendingMessageHandler.send(JmsSendingMessageHandler.java:143) [spring-integration-jms-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.integration.jms.JmsSendingMessageHandler.handleMessageInternal(JmsSendingMessageHandler.java:116) [spring-integration-jms-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127) [spring-integration-core-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116) [spring-integration-core-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:148) [spring-integration-core-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:121) [spring-integration-core-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:89) [spring-integration-core-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:423) [spring-integration-core-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.integration.channel.interceptor.WireTap.preSend(WireTap.java:168) [spring-integration-core-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.integration.channel.AbstractMessageChannel$ChannelInterceptorList.preSend(AbstractMessageChannel.java:538) [spring-integration-core-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:415) [spring-integration-core-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115) [spring-messaging-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.messaging.core.GenericMessagingTemplate.doSendAndReceive(GenericMessagingTemplate.java:150) [spring-messaging-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.messaging.core.GenericMessagingTemplate.doSendAndReceive(GenericMessagingTemplate.java:45) [spring-messaging-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.messaging.core.AbstractMessagingTemplate.sendAndReceive(AbstractMessagingTemplate.java:42) [spring-messaging-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.integration.core.MessagingTemplate.sendAndReceive(MessagingTemplate.java:97) [spring-integration-core-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.integration.gateway.MessagingGatewaySupport.doSendAndReceive(MessagingGatewaySupport.java:459) [spring-integration-core-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.integration.gateway.MessagingGatewaySupport.sendAndReceiveMessage(MessagingGatewaySupport.java:426) [spring-integration-core-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.integration.jms.ChannelPublishingJmsMessageListener$GatewayDelegate.sendAndReceiveMessage(ChannelPublishingJmsMessageListener.java:512) [spring-integration-jms-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.integration.jms.ChannelPublishingJmsMessageListener.onMessage(ChannelPublishingJmsMessageListener.java:344) [spring-integration-jms-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:721) [spring-jms-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:681) [spring-jms-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:651) [spring-jms-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:317) [spring-jms-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:255) [spring-jms-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1166) [spring-jms-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1158) [spring-jms-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1055) [spring-jms-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_131]
我知道这是由于ActiveMQMessage
类中的check ReadOnly
变量造成的,下面的方法对此负责
@Override
public void setObjectProperty(String name, Object value) throws JMSException {
setObjectProperty(name, value, true);
}
public void setObjectProperty(String name, Object value, boolean checkReadOnly) throws JMSException {
if (checkReadOnly) {
checkReadOnlyProperties();
}
if (name == null || name.equals("")) {
throw new IllegalArgumentException("Property name cannot be empty or null");
}
if (value instanceof UTF8Buffer) {
value = value.toString();
}
checkValidObject(value);
value = convertScheduled(name, value);
PropertySetter setter = JMS_PROPERTY_SETERS.get(name);
if (setter != null && value != null) {
setter.set(this, value);
} else {
try {
this.setProperty(name, value);
} catch (IOException e) {
throw JMSExceptionSupport.create(e);
}
}
}
private void checkReadOnlyProperties() throws MessageNotWriteableException {
if (readOnlyProperties) {
throw new MessageNotWriteableException("Message properties are read-only");
}
}
和DefaultJmsHeaderMapper
类ich捕获异常
并将其记录为WARN
@Override
public void fromHeaders(MessageHeaders headers, javax.jms.Message jmsMessage) {
try {
Object jmsCorrelationId = headers.get(JmsHeaders.CORRELATION_ID);
if (jmsCorrelationId instanceof Number) {
jmsCorrelationId = jmsCorrelationId.toString();
}
if (jmsCorrelationId instanceof String) {
try {
jmsMessage.setJMSCorrelationID((String) jmsCorrelationId);
}
catch (Exception e) {
this.logger.info("failed to set JMSCorrelationID, skipping", e);
}
}
Object jmsReplyTo = headers.get(JmsHeaders.REPLY_TO);
if (jmsReplyTo instanceof Destination) {
try {
jmsMessage.setJMSReplyTo((Destination) jmsReplyTo);
}
catch (Exception e) {
this.logger.info("failed to set JMSReplyTo, skipping", e);
}
}
Object jmsType = headers.get(JmsHeaders.TYPE);
if (jmsType instanceof String) {
try {
jmsMessage.setJMSType((String) jmsType);
}
catch (Exception e) {
this.logger.info("failed to set JMSType, skipping", e);
}
}
for (Entry<String, Object> entry : headers.entrySet()) {
String headerName = entry.getKey();
if (StringUtils.hasText(headerName) && !headerName.startsWith(JmsHeaders.PREFIX)
&& jmsMessage.getObjectProperty(headerName) == null) {
Object value = entry.getValue();
if (value != null) {
if (SUPPORTED_PROPERTY_TYPES.contains(value.getClass())) {
try {
String propertyName = this.fromHeaderName(headerName);
jmsMessage.setObjectProperty(propertyName, value);
}
catch (Exception e) {
if (headerName.startsWith("JMSX")
|| headerName.equals(IntegrationMessageHeaderAccessor.PRIORITY)) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("skipping reserved header, it cannot be set by client: "
+ headerName);
}
}
else if (this.logger.isWarnEnabled()) {
this.logger.warn("failed to map Message header '" + headerName + "' to JMS property", e); // **<-- this part**
}
}
}
else if (IntegrationMessageHeaderAccessor.CORRELATION_ID.equals(headerName)) {
String propertyName = fromHeaderName(headerName);
jmsMessage.setObjectProperty(propertyName, value.toString());
}
}
}
}
}
catch (Exception e) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("error occurred while mapping from MessageHeaders to JMS properties", e);
}
}
}
我知道这只是一个警告,但是我们希望保持日志干净,所以我们的想法是不要记录这个特定的WARN或尝试不传递头
。我已经基于DefaultJmsHeaderMapper
创建了一个自定义映射器并使用它,但是正如你在starckTrace中看到的,默认映射器仍在使用。
这里是XML文件中的配置
<bean id="voryouDuplicateCheckQueue" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg index="0" value="voryouDuplicateCheck${jms.queue.postfix}" />
</bean>
<bean id="voryouDuplicateCheckCustomJmsHeaderMapper" class="com.example.ws.impl.voryou.CustomJmsHeaderMapper" >
</bean>
<int-jms:inbound-gateway id="voryouDuplicateCheck"
request-destination="voryouDuplicateCheckQueue"
request-channel="voryouDuplicateCheckChannel"
extract-request-payload="false"
header-mapper="voryouDuplicateCheckCustomJmsHeaderMapper"
auto-startup="true"
/>
<int:channel id="voryouDuplicateCheckChannel">
<int:interceptors>
<int:wire-tap channel="loggingServiceChannel" />
</int:interceptors>
</int:channel>
<int:service-activator id="activatorSasoVoryouDuplicateCheck" input-channel="voryouDuplicateCheckChannel" ref="voryouDuplicateCheckBES"
method="getRequest" output-channel="loggingChannel" />
你们有没有遇到过类似的问题并找到了解决方案?主要目的不是记录这种类型的错误。
首先,4.3。x不再受支持。最后的4.3。x、 2020年底的版本为4.3.24。
其次,在消息创建期间,属性被标记为只读是很奇怪的。
避免日志的一种方法是将头映射器的日志级别设置为ERROR。
在Spring集成中使用出站网关时,我试图在JMS标头中发送回复Q详细信息。我了解到JIRA#INT-97中的增强功能在将Spring消息标头发送到JMS目标之前将其复制到JMS标头。 在将消息发送到出站网关之前,将消息头设置如下。message.getHeader(). setAtcm(JmsTargetAdapter.JMS_REPLY_TO, myReplyDestation); 但是我无法
我从一个xml模式生成java类,对于一个复杂类型,我希望jaxb使用一个现有的类,我有一个外部绑定定制文件。自定义类被解组为正确的,除了该类型的单个属性,该属性从未在java类中填充。 下面是类型/类问题的演示。 模式中定义的内容是: 读取匹配xml文件的代码段是: 在这个xml中阅读: 使用JAXB生成的Thing类(不使用自定义xjb),输出符合预期: 使用只有getters的自定义Thin
问题内容: 我阅读了今年的UberConf的幻灯片,其中一位发言者认为Spring JMS给您的消息队列系统增加了性能开销,但是在幻灯片中我看不到任何证据支持这一点。演讲者还提出了点对点比传统“发布- 订阅”方法更快的情况,因为每个消息仅发送一次,而不是广播给每个消费者。 我想知道是否有经验的Java消息传递专家可以在这里介绍一些技术问题: 使用Spring JMS而不是单纯的JMS实际上会产生性
版本: SpringBoot: 2.3.12。发布 SpringCloud:Hoxton。SR12 SpringCloud Starter Sleuth: 3.0.3 骆驼: 3.4.6 我想将Sleuth添加到一个预先存在的项目中,该项目现在使用ActiveMQ,以前它使用JMS。当我这样做时,ActiceMQ消息中的值会被阻止/删除(其中一个是“filename”,它是S2请求的键值)。其他J
我需要将源类中的字段值映射到字段属性。我可以使用Mapstruct使用@mapper注释的'expression'参数来完成 有没有其他方法可以不使用“表达式”来进行映射?
我有一个web应用程序,它通过WebLogic中的JMS与其他Java web应用程序通信。 我读到这样的答案:如何从PHP连接Jms? 我安装了ActiveMQ并尝试使用它。但是在Weblogic中,我们需要“jms_factory”和“queue_name”。我想它使用t3协议。