1

在解决了第一个阻止程序之后,我能够转向更复杂的场景,我尝试将自定义消息属性从我的 .NET 组件发送到 WebSphere Application Server v7 中托管的消息驱动 bean 和响应回 .NET 组件的消息驱动 bean . 这种通信是通过 WebSphere MQ v7 完成的,但 .NET 使用 WebSphere MQ Client v7.5 和 amqmdnet.dll v7.5.0.0(因为它修复了我在 v7 客户端中遇到的一些其他问题:例如this)。

我无法从 .NET 组件发送简单的布尔属性:

MQMessage message = new MQMessage();
message.SetBooleanProperty("TEST_BOOL", true);
queue.Put(message);

在消息驱动 bean 中接收此类消息将失败,并显示:

[8/3/12 17:37:20:087 CEST] 0000003b SibMessage    W   [:] CWSJY0003W: JMSCC0110: An exception '
                       Message : com.ibm.msg.client.jms.DetailedMessageFormatException: JMSCMQ1050: The MQRFH2 header has an incorrect format. Received a message with a badly formed MQRFH2 header. Ensure that any non-JMS applications building messages with MQRFH2 headers create well-formed MQRFH2 headers.
                         Class : class com.ibm.msg.client.jms.DetailedMessageFormatException
                         Stack : sun.reflect.NativeConstructorAccessorImpl.newInstance0(NativeConstructorAccessorImpl.java:-2)
                               : sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:45)
                               : sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:39)
                               : java.lang.reflect.Constructor.newInstance(Constructor.java:515)
                               : com.ibm.msg.client.commonservices.j2se.NLSServices.createException(NLSServices.java:313)
                               : com.ibm.msg.client.commonservices.nls.NLSServices.createException(NLSServices.java:388)
                               : com.ibm.msg.client.wmq.common.internal.messages.WMQMessageBase._parseUsrFolder(WMQMessageBase.java:1984)
                               : com.ibm.msg.client.wmq.common.internal.messages.WMQReceiveMarshal.constructProviderMessageFromRFH2(WMQReceiveMarshal.java:402)
                               : com.ibm.msg.client.wmq.common.internal.messages.WMQReceiveMarshal.constructProviderMessageFromProperties(WMQReceiveMarshal.java:191)
                               : com.ibm.msg.client.wmq.common.internal.messages.WMQReceiveMarshal.createProviderMessage(WMQReceiveMarshal.java:467)
                               : com.ibm.msg.client.wmq.common.internal.messages.WMQReceiveMarshal.exportProviderMessage(WMQReceiveMarshal.java:627)
                               : com.ibm.msg.client.wmq.internal.WMQConsumerShadow.getMsg(WMQConsumerShadow.java:1318)
                               : com.ibm.msg.client.wmq.internal.WMQConsumerShadow.getMsg(WMQConsumerShadow.java:1208)
                               : com.ibm.msg.client.wmq.internal.WMQSyncConsumerShadow.receive(WMQSyncConsumerShadow.java:366)
                               : com.ibm.msg.client.wmq.internal.WMQSession.loadMessageReference(WMQSession.java:1318)
                               : com.ibm.msg.client.jms.internal.JmsSessionImpl.consume(JmsSessionImpl.java:2940)
                               : com.ibm.msg.client.jms.internal.JmsSessionImpl.run(JmsSessionImpl.java:2631)
                               : com.ibm.mq.jms.MQSession.run(MQSession.java:862)
                               : com.ibm.mq.connector.inbound.WorkImpl.run(WorkImpl.java:265)
                               : com.ibm.ejs.j2c.work.WorkProxy.run(WorkProxy.java:399)
                               : com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1604)
     Caused by [1] --> Message : com.ibm.msg.client.jms.DetailedMessageFormatException: JMSCMQ0008: WebSphere MQ classes for JMS attempts to use a data type not supported by a message or attempts to read data in the wrong type. Wrong data types used to read message property types. Check that the message received and the properties to be read are of the type expected.
                         Class : class com.ibm.msg.client.jms.DetailedMessageFormatException
                         Stack : sun.reflect.NativeConstructorAccessorImpl.newInstance0(NativeConstructorAccessorImpl.java:-2)
                               : sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:45)
                               : sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:39)
                               : java.lang.reflect.Constructor.newInstance(Constructor.java:515)
                               : com.ibm.msg.client.commonservices.j2se.NLSServices.createException(NLSServices.java:313)
                               : com.ibm.msg.client.commonservices.nls.NLSServices.createException(NLSServices.java:388)
                               : com.ibm.msg.client.wmq.common.internal.messages.WMQMessageUtils.deformatTypedElement(WMQMessageUtils.java:306)
                               : com.ibm.msg.client.wmq.common.internal.messages.WMQMessageUtils.deformatElement(WMQMessageUtils.java:414)
                               : com.ibm.msg.client.wmq.common.internal.messages.WMQMessageBase._parseUsrFolder(WMQMessageBase.java:1963)
                               : com.ibm.msg.client.wmq.common.internal.messages.WMQReceiveMarshal.constructProviderMessageFromRFH2(WMQReceiveMarshal.java:402)
                               : com.ibm.msg.client.wmq.common.internal.messages.WMQReceiveMarshal.constructProviderMessageFromProperties(WMQReceiveMarshal.java:191)
                               : com.ibm.msg.client.wmq.common.internal.messages.WMQReceiveMarshal.createProviderMessage(WMQReceiveMarshal.java:467)
                               : com.ibm.msg.client.wmq.common.internal.messages.WMQReceiveMarshal.exportProviderMessage(WMQReceiveMarshal.java:627)
                               : com.ibm.msg.client.wmq.internal.WMQConsumerShadow.getMsg(WMQConsumerShadow.java:1318)
                               : com.ibm.msg.client.wmq.internal.WMQConsumerShadow.getMsg(WMQConsumerShadow.java:1208)
                               : com.ibm.msg.client.wmq.internal.WMQSyncConsumerShadow.receive(WMQSyncConsumerShadow.java:366)
                               : com.ibm.msg.client.wmq.internal.WMQSession.loadMessageReference(WMQSession.java:1318)
                               : com.ibm.msg.client.jms.internal.JmsSessionImpl.consume(JmsSessionImpl.java:2940)
                               : com.ibm.msg.client.jms.internal.JmsSessionImpl.run(JmsSessionImpl.java:2631)
                               : com.ibm.mq.jms.MQSession.run(MQSession.java:862)
                               : com.ibm.mq.connector.inbound.WorkImpl.run(WorkImpl.java:265)
                               : com.ibm.ejs.j2c.work.WorkProxy.run(WorkProxy.java:399)
                               : com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1604)
' was caught while processing a message for delivery to a message driven bean.
4

3 回答 3

1

我使用RFHUtils来获取我的 .NET 组件发送的消息。usrRFH2 文件夹包含以下定义:

TEST_BOOL(dt='boolean')=True

如果我将值更改为,1而不是True使用 RFHUtils 发送消息,它会被正确处理。反编译的资源适配器(我正在使用JD-GUI)也表明它只需要布尔 JMS 属性01值。

static Object deformatTypedElement(int datatype, String value)
    throws JMSException
{
    Object result = null;
    switch (datatype) {
        ...
        case 1:
            if (value.equals("1")) {
                result = new Boolean(true);
            }
            else if (value.equals("0")) {
                result = new Boolean(false);
            }
            else {
                JMSException je = (JMSException)NLSServices.createException("JMSCMQ0008", null); // Line 306 - BOOM!
                throw je;
            }

            // There is also no break here but I think it is a problem of decompiler
       ...
    }
}

.NET 的 amqmdnet.dll 库的反编译代码(我正在使用.NET Reflector)表明它在将布尔值传递给消息之前不会转换它们。它只是ToString()在值上使用:

internal class MQMarshalMessageForPut : MQBaseObject
{
   ...

   private void SetContent(RFH2Folder element, object value)
   {
       ...

       if (value is bool)
       {
           element.SetContent(value.ToString(), 1);
       }

       ...
    }
} 

但是ToStringbool类型返回TrueFalse

从消息驱动的 bean 返回到 .NET 应用程序的响应没有任何问题,因为GetBoolProperty准备好同时处理TrueFalse字符串01值。

private bool ParseBoolean(object obj) 
{
    ...

    if ((string.Compare(strA, "true", true) == 0) || (strA == "1"))
    {
        strA = bool.TrueString;
    }
    else if ((string.Compare(strA, "false", true) == 0) || (strA == "0"))
    {
        strA = bool.FalseString;
    }


    ...
}

我认为这是 IBM amqmdnet.dll 库中的一个错误。

于 2012-08-06T11:37:33.333 回答
1

这是一个错误,正确的行为应该允许应用程序使用布尔值的编程语言表示。在这种情况下,.NET 为“真/假”,JMS 为 1/0。MQ 应该在两个应用程序之间转换布尔值。

现在已经解决了这个问题。

于 2016-03-01T21:24:31.673 回答
0

TrueBoolean和有不同的定义False。有些语言将 True 表示为 1,将 False 表示为 0,而有些语言将 False 定义为 0,将任何非零(包括 1 和 -1)定义为 True。有些像 Ruby 将 True 定义为 0。所以不能肯定地说 True 是 1 而 False 是 0。所以 MQ .NET 和 Java API 将布尔值设置为本身,接收应用程序可以根据它们的语言细节来解释它TrueFalse

然而,在消息接收期间,MQ .NET 和 Java API 确实将 1 识别为 True,0 识别为 false。这更像是一个可用性点。发送消息时不能应用相同的值,始终必须设置一致的值,有时不能设置为 1,有时设置为 True。

于 2012-08-07T04:52:46.013 回答