2012-08-06 17 views
1

解決之後the first blocker我能夠轉向更復雜的場景,我嘗試從我的.NET組件向客戶發送消息屬性,將JMS消息發送到WebSphere Application Server v7中託管的消息驅動Bean,並將bean響應回.NET組件。此通信通過WebSphere MQ v7完成,但.NET使用WebSphere MQ Client v7.5和amqmdnet.dll v7.5.0.0(因爲它解決了我與v7客戶端有關的其他一些問題:例如this)。如何將用戶的布爾屬性從WMQ .NET客戶端API發送到JMS?

我無法從.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. 

回答

1

我以前RFHUtils獲得由我的.NET組件發送的消息。 usr RFH2文件夾中包含這樣的定義:

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 
     ... 
    } 
} 

反編譯amqmdnet.dll庫.NET(我使用.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庫中的一個錯誤。

0

布爾TrueFalse有不同的定義。有些語言表示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。

+0

是的。有不同的表示方式,因此您必須能夠控制發送消息時使用的表示形式。例如通過在'SetBooleanProperty'中提供附加參數。您正在捍衛.NET應用程序無法將布爾屬性發送到僅期望'0'或'1'的目標的狀態(這應該是btw默認表示,因爲它比'True'或'False'更普遍)。 – 2012-08-07 07:45:57

1

這是一個錯誤,正確的行爲應該允許應用程序使用布爾值的編程語言表示。在這種情況下,.NET是「真/假」,JMS是1/0。 MQ應該轉換兩個應用程序之間的布爾值。

現在已經修復。

相關問題