骆驼使用来自 queue 的消息但无法重新创建它

Camel consuming message from queue but fails to recreate it

我遇到了一个问题,我的对手将消息放在 Oracle 的 JMS TEXT queue 上(一些自定义应用程序不使用 java),我要接收它。路线很简单:

<!--Receive data from oracle queue -->
<route id="ReadFromQueue" autoStartup="true">
    <from uri="oracleQueue:queue:SCAQUSER.SCD2TC?jmsMessageType=Text" />
    <log message="Picked up message ${body}" />
    <to uri="file:/e:/Tradechannel/in" />
</route>

连接已建立,运行 并且我的路由会在 queue 中放置消息时立即响应。当 运行 带有 oracle.jms.traceLevel=6 的代码时,至少在我看来一切似乎都正常工作。

Camel (camel-1) thread #4 - JmsConsumer[SCAQUSER.SCD2TC] [Thu Dec 19 10:08:44 CET 2019] AQjmsConsumer.jdbcDequeue:  Timeout: 1 seconds.  Iterations: 1 Interval: 120 Last interval: 1
Camel (camel-1) thread #4 - JmsConsumer[SCAQUSER.SCD2TC] [Thu Dec 19 10:08:44 CET 2019] AQjmsConsumer.jdbcDequeue:  wait time: 1
Camel (camel-1) thread #4 - JmsConsumer[SCAQUSER.SCD2TC] [Thu Dec 19 10:08:44 CET 2019] AQjmsConsumer.jdbcDequeue:  payload type:SYS.AQ$_JMS_TEXT_MESSAGEpayload type code:2002
Camel (camel-1) thread #4 - JmsConsumer[SCAQUSER.SCD2TC] [Thu Dec 19 10:08:44 CET 2019] AQjmsSession.getCompliant:  Session :false
Camel (camel-1) thread #4 - JmsConsumer[SCAQUSER.SCD2TC] [Thu Dec 19 10:08:44 CET 2019] AQjmsUtil.getTextData:  entry
Camel (camel-1) thread #4 - JmsConsumer[SCAQUSER.SCD2TC] [Thu Dec 19 10:08:44 CET 2019] AQjmsUtil.getTextData:  textLen: 288
Camel (camel-1) thread #4 - JmsConsumer[SCAQUSER.SCD2TC] [Thu Dec 19 10:08:44 CET 2019] AQjmsUtil.getTextData:  exit
Camel (camel-1) thread #4 - JmsConsumer[SCAQUSER.SCD2TC] [Thu Dec 19 10:08:44 CET 2019] AQjmsConsumer.jdbcDequeue:  text_message retrieved
Camel (camel-1) thread #4 - JmsConsumer[SCAQUSER.SCD2TC] [Thu Dec 19 10:08:44 CET 2019] AQjmsConsumer.jdbcDequeue:  set AQ enqueue time as 1576249545000
Camel (camel-1) thread #4 - JmsConsumer[SCAQUSER.SCD2TC] [Thu Dec 19 10:08:44 CET 2019] AQjmsConsumer.jdbcDequeue:  msg_id: 999832415E09038AE0535C35EB751E09 corrid: null priority: 1
Camel (camel-1) thread #4 - JmsConsumer[SCAQUSER.SCD2TC] [Thu Dec 19 10:08:44 CET 2019] AQjmsConsumer.jdbcDequeue:  msg_delay(secs): 0
Camel (camel-1) thread #4 - JmsConsumer[SCAQUSER.SCD2TC] [Thu Dec 19 10:08:44 CET 2019] AQjmsConsumer.jdbcDequeue:  exptime(secs): -1
Camel (camel-1) thread #4 - JmsConsumer[SCAQUSER.SCD2TC] [Thu Dec 19 10:08:44 CET 2019] AQjmsConsumer.jdbcDequeue:  attempts: 0
Camel (camel-1) thread #4 - JmsConsumer[SCAQUSER.SCD2TC] [Thu Dec 19 10:08:44 CET 2019] AQjmsConsumer.jdbcDequeue:  exception queue: null
Camel (camel-1) thread #4 - JmsConsumer[SCAQUSER.SCD2TC] [Thu Dec 19 10:08:44 CET 2019] AQjmsSession.getCompliant:  Session :false
Camel (camel-1) thread #4 - JmsConsumer[SCAQUSER.SCD2TC] [Thu Dec 19 10:08:44 CET 2019] AQjmsConsumer.jdbcDequeue:  recv_time: 1576746524523
Camel (camel-1) thread #4 - JmsConsumer[SCAQUSER.SCD2TC] [Thu Dec 19 10:08:44 CET 2019] AQjmsSession.inGlobalTransRechecked:  entry
Camel (camel-1) thread #4 - JmsConsumer[SCAQUSER.SCD2TC] [Thu Dec 19 10:08:44 CET 2019] AQjmsSession.inGlobalTransRechecked:  oracle.jms.useEmulatedXA is on
Camel (camel-1) thread #4 - JmsConsumer[SCAQUSER.SCD2TC] [Thu Dec 19 10:08:44 CET 2019] EmulatedXAHandler.inGlobalTrans:  entry, reCheck=true
Camel (camel-1) thread #4 - JmsConsumer[SCAQUSER.SCD2TC] [Thu Dec 19 10:08:44 CET 2019] EmulatedXAHandler.checkForGlobalTxn:  entry
Camel (camel-1) thread #4 - JmsConsumer[SCAQUSER.SCD2TC] [Thu Dec 19 10:08:44 CET 2019] EmulatedXAHandler.inGlobalTrans:  exit
Camel (camel-1) thread #4 - JmsConsumer[SCAQUSER.SCD2TC] [Thu Dec 19 10:08:44 CET 2019] AQjmsSession.inGlobalTransRechecked:  exit
Camel (camel-1) thread #4 - JmsConsumer[SCAQUSER.SCD2TC] [Thu Dec 19 10:08:44 CET 2019] AQjmsSession.restartConsumers:  entry
Camel (camel-1) thread #4 - JmsConsumer[SCAQUSER.SCD2TC] [Thu Dec 19 10:08:44 CET 2019] AQjmsConsumer.doCommit:  acknowledged one message received by committing the database connection
Camel (camel-1) thread #4 - JmsConsumer[SCAQUSER.SCD2TC] [Thu Dec 19 10:08:44 CET 2019] AQjmsConsumer.jdbcDequeue:  exit

消息已从 queue 中删除,但在我的应用程序日志中出现错误...

2019-12-19 10:08:44:554 o.a.c.c.jms.EndpointMessageListener WARN  - Execution of JMS message listener failed. Caused by: [org.apache.camel.RuntimeCamelException - JMSXGroupSeq]
org.apache.camel.RuntimeCamelException: JMSXGroupSeq
    at org.apache.camel.component.jms.JmsBinding.extractHeadersFromJms(JmsBinding.java:225)
    at org.apache.camel.component.jms.JmsMessage.populateInitialHeaders(JmsMessage.java:235)
    at org.apache.camel.impl.DefaultMessage.createHeaders(DefaultMessage.java:258)
    at org.apache.camel.component.jms.JmsMessage.ensureInitialHeaders(JmsMessage.java:220)
    at org.apache.camel.component.jms.JmsMessage.getHeader(JmsMessage.java:170)
    at org.apache.camel.impl.DefaultMessage.getHeader(DefaultMessage.java:94)
    at org.apache.camel.impl.DefaultUnitOfWork.(DefaultUnitOfWork.java:115)
    at org.apache.camel.impl.DefaultUnitOfWork.(DefaultUnitOfWork.java:75)
    at org.apache.camel.impl.DefaultUnitOfWorkFactory.createUnitOfWork(DefaultUnitOfWorkFactory.java:34)
    at org.apache.camel.processor.CamelInternalProcessor$UnitOfWorkProcessorAdvice.createUnitOfWork(CamelInternalProcessor.java:695)
    at org.apache.camel.processor.CamelInternalProcessor$UnitOfWorkProcessorAdvice.before(CamelInternalProcessor.java:663)
    at org.apache.camel.processor.CamelInternalProcessor$UnitOfWorkProcessorAdvice.before(CamelInternalProcessor.java:634)
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:149)
    at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:97)
    at org.apache.camel.component.jms.EndpointMessageListener.onMessage(EndpointMessageListener.java:113)
    at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:736)
    at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:696)
    at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:674)
    at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:318)
    at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:257)
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1189)
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1179)
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1076)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: javax.jms.MessageFormatException: JMS-117: Conversion failed - invalid property type
    at oracle.jms.AQjmsError.throwMsgFormatEx(AQjmsError.java:452)
    at oracle.jms.AQjmsMessage.getObjectProperty(AQjmsMessage.java:1584)
    at org.apache.camel.component.jms.JmsMessageHelper.getProperty(JmsMessageHelper.java:118)
    at org.apache.camel.component.jms.JmsBinding.extractHeadersFromJms(JmsBinding.java:214)
    ... 25 common frames omitted

如果我正确理解堆栈跟踪,它是缺少 header JMSXGroupSeq 的 oracle.jms api 这不太可能,因为对方没有使用 oracle jms api 来创建消息。他和我都无法查看实际的 queue(它在我们共同的客户端),因此我无法检查实际存在的 header。

使用自定义 headerFilterStrategy 没有帮助,因为在我到达 headerFilterStrategy 之前就抛出了错误。请参阅下面从 org.apache.camel.component.jms.JmsBinding 方法 extractHeadersFromJms 中提取的内容。错误是从 JmsMessageHelper.getProperty()

抛出的
Object value = JmsMessageHelper.getProperty(jmsMessage, name);
if (headerFilterStrategy != null 
 && headerFilterStrategy.applyFilterToExternalHeaders(name, value, exchange)) {
 continue;
 }

所以我的第一个问题是...

是否可以收到可能是"invalid"的消息-我可以让camel和oracleapi忽略missing/invalidheaders吗?

第二个问题...为什么 Oracle 确认消息时好像一切正​​常,而实际上消息从未在接收方成功重新创建?

由于错误消息 "Conversion failed",我怀疑 JMS 属性 JMSXGroupSeq 有一个 无效类型

因为 Camel 只是试图在 JmsMessageHelper.getProperty 中读取这个值 我想这个 属性.[=17= 中一定有一些非常奇怪的值]

您是否尝试使用 JMS Toolbox 等工具查看 这样的消息?如果您看到 属性 值,您或许可以建议生产者如何修复它。

回答您的问题:

是否可以收到可能是"invalid"的消息?

对于 Camel,我不这么认为。 Camel 擅长让您的生活变得方便,因此可以完成所有 low-level 的事情,并为您提供一个很好的交流 object 里面有消息。

如果在这部分抛出异常,我猜你运气不好,因为正如你已经提到的,它在你干预之前就抛出了。这隐含地表明这种情况的发生是多么罕见,这个 属性 值一定是多么奇怪。

但是,您当然可以使用其他东西来使用消息。有些东西不会尝试自动读取所有 headers,但至少会完成 JMS 的 low-level 工作。也许 Spring JMS 会成为候选人。 Camel JMS 在后台使用 Spring JMS。

为什么 Oracle 会确认消息?

对于 属性 JMSXGroupSeq JMS Docs

JMSXGroupID and JMSXGroupSeq are standard properties that clients should use if they want to group messages. All providers must support them. Unless specifically noted, the values and semantics of the JMSX properties are undefined.

如果值未定义,则 Broker 无法用来验证任何内容。