我遇到一个问题,我的对方正在将消息放在Oracle上的JMS TEXT队列上(某些自定义应用程序未使用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>
连接已建立并且正在运行,并且当消息放入队列时,我的路由会立即做出响应。当使用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
该消息已从队列中删除,但是在我的应用程序日志中,我收到错误消息...
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
如果我正确理解了堆栈跟踪,那是oracle.jms api缺少标头 JMSXGroupSeq ,这很常见,因为对方没有使用oracle jms api创建消息。他和我都无法查看实际的队列(在我们共同的客户一方),因此我无法检查实际上有什么标题。
使用自定义的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;
}
所以我的第一个问题是...
是否有可能收到可能是“无效”的消息-我可以让骆驼和oracle api忽略丢失/无效的标头吗?
第二个问题...为什么甲骨文在实际上从未成功在接收方成功创建消息的情况下将消息确认为一切正常?
答案 0 :(得分:0)
由于错误消息“转换失败”,我怀疑JMS属性JMSXGroupSeq
的类型为无效。
由于骆驼只是尝试在JmsMessageHelper.getProperty
中读取此值,所以我猜想此属性中肯定有一些非常奇怪的值。
您是否曾经尝试使用JMS Toolbox之类的工具来偷窥这样的消息?如果看到财产价值,您可能会建议生产者如何解决它。
要回答您的问题:
我不相信Camel。 Camel擅长使您的生活变得方便,因此可以处理所有低级内容,并为您提供了一个带有Messages的漂亮Exchange对象。
如果在该部分中引发异常,我想您很不走运,因为,正如您已经提到的,在您进行干预之前就抛出了异常。这隐式显示了这种情况的发生率,以及该属性值必须是多么奇怪。
但是,您当然可以使用其他方式使用消息。不会尝试自动读取所有标头,但至少可以完成JMS的低级工作的东西。也许Spring JMS将是候选人。 Camel JMS在后台使用Spring JMS。
对于财产JMSXGroupSeq
,JMS Docs说
JMSXGroupID和JMSXGroupSeq是客户端要对消息进行分组时应使用的标准属性。所有提供者都必须支持他们。除非特别说明,否则JMSX属性的值和语义是不确定的。
如果值未定义,则Broker无法使用任何值进行验证。