我正在尝试从ActiveMQ队列中获取消息并将其传递给Websphere MQ队列。
我正在使用WSO2,因为我们最终会想要使用它为我们提供的所有功能。
问题似乎是WSO2试图将ActiveMQ MessageId作为Correlation Id直接传递给Websphere MQ--格式错误。
我试图删除TRANSPORT_HEADERS,但我一定是做错了。
我在inSequence中添加了一个虚拟属性JMS_CORRELATION_ID(根据此post)以查看是否可以验证这一点,但Websphere MQ似乎无法识别此标头。
很高兴将消息从Websphere MQ传递到ActiveMQ在我创建的另一个代理服务中运行良好。在这种情况下,Websphere MQ消息ID将传递给Active MQ相关ID。
这是例外
[2013-03-08 12:18:23,414] ERROR - JMSSender Error creating a JMS message from the message context
com.ibm.msg.client.jms.DetailedJMSException: JMSCMQ1044: String is not a valid hexadecimal number - 'dolguldur-51590-1362693989456-3:4:1:1:4'.
Either an attempt was made to specify a group ID or correlation ID which starts with the prefix ID but is not followed by a well-formed hexadecimal value, or an attempt was made to receive a message w
hich contains an MQRFH2 property of type bin.hex that does not have a well-formed hexadecimal value.
Ensure that a valid hexadecimal value always follows the ID prefix when setting group ID or correlation ID values. Ensure that any MQRFH2 headers generated by non-JMS applications are well-formed.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at com.ibm.msg.client.commonservices.j2se.NLSServices.createException(NLSServices.java:319)
at com.ibm.msg.client.commonservices.nls.NLSServices.createException(NLSServices.java:233)
at com.ibm.msg.client.wmq.common.internal.WMQUtils.hexToBin(WMQUtils.java:414)
at com.ibm.msg.client.wmq.common.internal.WMQUtils.stringToId(WMQUtils.java:496)
at com.ibm.msg.client.wmq.common.internal.messages.WMQMessageHeader.setJMSCorrelationID(WMQMessageHeader.java:314)
at com.ibm.msg.client.jms.internal.JmsMessageImpl.setJMSCorrelationID(JmsMessageImpl.java:610)
at com.ibm.jms.JMSMessage.setJMSCorrelationID(JMSMessage.java:1133)
at org.apache.axis2.transport.jms.JMSSender.createJMSMessage(JMSSender.java:428)
at org.apache.axis2.transport.jms.JMSSender.sendOverJMS(JMSSender.java:172)
at org.apache.axis2.transport.jms.JMSSender.sendMessage(JMSSender.java:154)
at org.apache.axis2.transport.base.AbstractTransportSender.invoke(AbstractTransportSender.java:112)
at org.apache.axis2.engine.AxisEngine$TransportNonBlockingInvocationWorker.run(AxisEngine.java:626)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
[2013-03-08 12:18:23,417] INFO - AxisEngine [MessageContext: logID=a7a3184cd19f3b5ab7a012af40cd7840329dd8fc40d0e9c3] Error creating a JMS message from the message context
WSO2代理服务配置
<proxy xmlns="http://ws.apache.org/ns/synapse" name="TestService" transports="jms" statistics="disable" trace="disable" startOnLoad="true">
<target>
<inSequence>
<property name="TRANSPORT_HEADERS" scope="transport" action="remove"/>
<property name="OUT_ONLY" value="true"/>
<log level="full"/>
</inSequence>
<endpoint>
<address uri="jms:/QUEUE.OUT?transport.jms.ConnectionFactory=ibmMQQueueConnectionFactory"/>
</endpoint>
</target>
<parameter name="transport.jms.ConnectionFactory">activeMQQueueConnectionFactory</parameter>
<parameter name="transport.jms.Destination">TESTJMS.IN</parameter>
<description></description>
</proxy>
axis2.xml传输接收器
<transportReceiver name="jms" class="org.apache.axis2.transport.jms.JMSListener">
<parameter name="activeMQQueueConnectionFactory" locked="false">
<parameter name="java.naming.factory.initial" locked="false">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter>
<parameter name="java.naming.provider.url" locked="false">tcp://localhost:61616</parameter>
<parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">QueueConnectionFactory</parameter>
<parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
</parameter>
<parameter name="ibmMQQueueConnectionFactory" locked="false">
<parameter name="java.naming.factory.initial" locked="false">com.sun.jndi.fscontext.RefFSContextFactory</parameter>
<parameter name="java.naming.provider.url" locked="false">file:/E:/work/MQ-JNDI-Directory</parameter>
<parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">ConnectionFactoryTest</parameter>
<parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
</parameter>
</transportReceiver>
axis2.xml传输发件人
org.apache.activemq.jndi.ActiveMQInitialContextFactory TCP://本地主机:61616 的QueueConnectionFactory 队列
<parameter name="ibmMQQueueConnectionFactory" locked="false">
<parameter name="java.naming.factory.initial" locked="false">com.sun.jndi.fscontext.RefFSContextFactory</parameter>
<parameter name="java.naming.provider.url" locked="false">file:/E:/work/MQ-JNDI-Directory</parameter>
<parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">ConnectionFactoryTest</parameter>
<parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
</parameter>
干杯, 史蒂夫
11/3更多信息
所以看起来当我在ActiveMQ消息中放入一个简单字符串之类的相关ID时,我没有收到错误'JMSCMQ1044:字符串不是有效的十六进制数'。
因此,从活动MQ到Websphere MQ关联ID的映射存在问题。
但这是我现在得到的错误 - 看起来像类org.apache.axis2.transport.jms.JMSUtils正在尝试设置JMS_DESTINATION标头而Websphere MQ不允许这样做?
我通过编写一个简单的Java客户端并尝试设置头JMS_DESTINATION来验证这一点,我从Websphere MQ得到了同样的错误。
我可以让Websphere MQ处理这些标头吗?或让JMSSender以不同的方式发布消息?或者org.apache.axis2.transport.jms.JMSSender根本不能与Websphere MQ一起使用?
顺便说一下,我正在使用最新的Websphere MQ 7.5。
[2013-03-11 09:33:20,378] DEBUG - JMSMessageReceiver Received new JMS message for service :TestService
Destination : queue://TESTJMS.IN
Message ID : ID:dolguldur-50398-1362951749472-3:2:1:1:24
Correlation ID : NONE
ReplyTo : null
Redelivery ? : false
Priority : 0
Expiration : 0
Timestamp : 1362958400374
Message Type :
Persistent ? : false
[2013-03-11 09:33:20,380] TRACE - JMSMessageReceiver
Message : Enter some text here for the message body...
[2013-03-11 09:33:20,381] INFO - LogMediator To: , WSAction: urn:mediate, SOAPAction: urn:mediate, MessageID: ID:dolguldur-50398-1362951749472-3:2:1:1:24, Direction: request, Envelope: <?xml version=
'1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><axis2ns5:text xmlns:axis2ns5="http://ws.apache.org/commons/ns/payload">Enter some tex
t here for the message body...</axis2ns5:text></soapenv:Body></soapenv:Envelope>
[2013-03-11 09:33:20,388] DEBUG - JMSConnectionFactory Creating a new JMS Session from JMS CF : ibmMQQueueConnectionFactory
[2013-03-11 09:33:20,392] DEBUG - JMSConnectionFactory Creating a new JMS MessageProducer from JMS CF : ibmMQQueueConnectionFactory
[2013-03-11 09:33:20,393] ERROR - JMSSender Error creating a JMS message from the message context
com.ibm.msg.client.jms.DetailedMessageFormatException: JMSCC0050: The property name 'JMS_DESTINATION' is reserved and cannot be set.
The supplied property name begins with the JMS prefix, but is not one of the supported, settable properties.
Check the property name and correct errors.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at com.ibm.msg.client.commonservices.j2se.NLSServices.createException(NLSServices.java:319)
at com.ibm.msg.client.commonservices.nls.NLSServices.createException(NLSServices.java:233)
at com.ibm.msg.client.jms.internal.JmsErrorUtils.createException(JmsErrorUtils.java:109)
at com.ibm.msg.client.jms.internal.JmsMessageImpl.checkSettablePropertyName(JmsMessageImpl.java:2125)
at com.ibm.msg.client.jms.internal.JmsMessageImpl.setStringProperty(JmsMessageImpl.java:1560)
at com.ibm.jms.JMSMessage.setStringProperty(JMSMessage.java:1496)
at org.apache.axis2.transport.jms.JMSUtils.setTransportHeaders(JMSUtils.java:278)
at org.apache.axis2.transport.jms.JMSSender.createJMSMessage(JMSSender.java:441)
at org.apache.axis2.transport.jms.JMSSender.sendOverJMS(JMSSender.java:172)
at org.apache.axis2.transport.jms.JMSSender.sendMessage(JMSSender.java:154)
at org.apache.axis2.transport.base.AbstractTransportSender.invoke(AbstractTransportSender.java:112)
at org.apache.axis2.engine.AxisEngine$TransportNonBlockingInvocationWorker.run(AxisEngine.java:626)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
[2013-03-11 09:33:20,399] ERROR - AsyncCallback Error creating a JMS message from the message context
org.apache.axis2.AxisFault: Error creating a JMS message from the message context
at org.apache.axis2.transport.base.AbstractTransportSender.handleException(AbstractTransportSender.java:226)
at org.apache.axis2.transport.jms.JMSSender.sendOverJMS(JMSSender.java:174)
at org.apache.axis2.transport.jms.JMSSender.sendMessage(JMSSender.java:154)
at org.apache.axis2.transport.base.AbstractTransportSender.invoke(AbstractTransportSender.java:112)
at org.apache.axis2.engine.AxisEngine$TransportNonBlockingInvocationWorker.run(AxisEngine.java:626)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Caused by: com.ibm.msg.client.jms.DetailedMessageFormatException: JMSCC0050: The property name 'JMS_DESTINATION' is reserved and cannot be set.
The supplied property name begins with the JMS prefix, but is not one of the supported, settable properties.
Check the property name and correct errors.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at com.ibm.msg.client.commonservices.j2se.NLSServices.createException(NLSServices.java:319)
at com.ibm.msg.client.commonservices.nls.NLSServices.createException(NLSServices.java:233)
at com.ibm.msg.client.jms.internal.JmsErrorUtils.createException(JmsErrorUtils.java:109)
at com.ibm.msg.client.jms.internal.JmsMessageImpl.checkSettablePropertyName(JmsMessageImpl.java:2125)
at com.ibm.msg.client.jms.internal.JmsMessageImpl.setStringProperty(JmsMessageImpl.java:1560)
at com.ibm.jms.JMSMessage.setStringProperty(JMSMessage.java:1496)
at org.apache.axis2.transport.jms.JMSUtils.setTransportHeaders(JMSUtils.java:278)
at org.apache.axis2.transport.jms.JMSSender.createJMSMessage(JMSSender.java:441)
at org.apache.axis2.transport.jms.JMSSender.sendOverJMS(JMSSender.java:172)
... 6 more
答案 0 :(得分:1)
这是因为WebSphere MQ遵循JMS规范,该规范声明消息ID始终由传输提供程序设置。请参阅JMS 1.1 specification:
3.4.3 JMSMessageID
JMSMessageID标头字段包含唯一标识每个标头的值
提供者发送的消息。
发送消息时,将忽略JMSMessageID。当发送方法 返回时,该字段包含提供者分配的值。
WMQ信息中心主题Mapping JMS header fields at send() or publish()证实了这一点:
从JMS发送的所有消息都具有由其分配的唯一消息标识符 WebSphere®MQ。分配的值在MQMD.MessageId中返回 MQPUT调用后的字段,并传递回应用程序中 JMSMessageID字段。 WebSphere MQ messageId是一个24字节的二进制文件 值,而JMSMessageID是一个字符串。 JMSMessageID是 由二进制messageId值组成,转换为48的序列 十六进制字符,前缀为字符ID:。 JMS提供 一个提示,可以设置为禁用消息的生成 身份标识。忽略此提示,并分配唯一标识符 在所有情况下。之前在JMSMessageId字段中设置的任何值 一个send()被覆盖。
您可以缓存消息ID并在它们通过代理时关联它们,或者可以通过退出JMS API并使用Java本机API发送消息来完成。假设您使用的是现代版本的WebSphere MQ,JMS消息不再需要RFH2头,而是将JMS属性作为本机WMQ消息属性。这意味着JMS应用程序可以在大多数情况下读取本机WMQ消息,就像它们是JMS消息一样,假设应用程序使用现代QMgr和现代版本的JMS类。
如果您需要更新,最新的WMQ客户端和JMS类位于SupportPac MQC75。