1

我正在尝试从 ActiveMQ 队列中提取消息并将其传递给 Websphere MQ 队列。

我正在使用 WSO2,因为最终我们会想要使用它提供给我们的所有功能。

问题似乎是 WSO2 尝试将 ActiveMQ MessageId 作为 Correlation Id 直接传递给 Websphere MQ - 格式错误。

我试图删除 TRANSPORT_HEADERS 但我一定做错了什么。

我在 inSequence 中添加了一个虚拟属性 JMS_CORRELATION_ID(根据这篇文章),以查看是否可以验证这一点,但 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://localhost: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
4

1 回答 1

1

这是因为 WebSphere MQ 遵循 JMS 规范,该规范声明消息 ID 始终由传输提供者设置。请参阅JMS 1.1 规范


3.4.3 JMSMessageID
JMSMessageID 头域包含一个唯一标识提供者发送的每条消息的值。

发送消息时,将忽略 JMSMessageID。当 send 方法返回时,该字段包含一个提供者分配的值。


这在 WMQ 信息中心主题Mapping JMS header fields at send() or publish()中得到证实,其中说:

从 JMS 发送的所有消息都具有由 WebSphere® MQ 分配的唯一消息标识符。分配的值在 MQPUT 调用之后在 MQMD.MessageId 字段中返回,并在 JMSMessageID 字段中传递回应用程序。WebSphere MQ messageId 是一个 24 字节的二进制值,而 JMSMessageID 是一个字符串。JMSMessageID 由转换为 48 个十六进制字符序列的二进制 messageId 值组成,前缀为字符 ID:。JMS 提供了一个提示,可以设置为禁用生成消息标识符。忽略此提示,并在所有情况下分配唯一标识符。在 send() 被覆盖之前设置到 JMSMessageId 字段中的任何值。

您可以缓存消息 ID 并在它们通过代理时关联它们,或者可以通过退出 JMS API 并使用 Java 本机 API 发送消息来完成。假设您使用的是现代版本的 WebSphere MQ,JMS 消息不再需要 RFH2 标头,而是将 JMS 属性作为本机 WMQ 消息属性。这意味着在大多数情况下,JMS 应用程序可以读取本机 WMQ 消息,就好像它们是 JMS 消息一样,假设应用程序使用现代 QMgr 和 JMS 类的现代版本。

如果您需要更新,最新的 WMQ 客户端和 JMS 类位于SupportPac MQC75 。

于 2013-03-08T16:32:48.553 回答