2012-06-13 32 views
2

我們使用XMS.Net連接到WebSphere MQ服務器V7;這對V6服務器來說一直運行良好,但自從「另一方」升級到V7後,我們遇到了一些麻煩。它的大部分已得到修復,但現在我已經在一個偶然的錯誤,我無法解釋,也沒有找到任何東西:XMS.Net 2.1.0.0/1 CWSMQ0282E

CWSMQ0282E: A null value has been used for argument BUFFER = <> NULL within method ImportMQMDMesageBuffer(WmqSession, WmqDestination, MQMD,byte[],int,int). 
The preceding method detected an invalid null argument. 
If necessary, recode the application to avoid the error condition. 
Stacktrace: at IBM.XMS.Client.WMQ.WmqReceiveMarshal.ImportMQMDMesageBuffer(MQMessageDescriptor mqmd, Byte[] buffer, Int32 dataStart, Int32 dataEnd) 
    at IBM.XMS.Client.WMQ.WmqAsyncConsumerShadow.Consumer(Phconn hconn, MQMessageDescriptor mqmd, MQGetMessageOptions mqgmo, Byte[] pBuffer, MQCBC mqcbc) 
    at IBM.WMQ.Nmqi.UnmanagedNmqiMQ.NmqiConsumerMethodUM(Int32 hconn, IntPtr structMqmd, IntPtr structMqgmo, IntPtr buffer, IntPtr structMqcbc) 

有關此錯誤的原因是我唯一認爲我知道我們發送了一條消息,並期待CoA和CoD消息;我期待這些消息在隊列中,當我關閉消費者收聽這些消息時,其他消息正常工作。

我完全不知道是怎麼回事......

編輯

這是起碼的測試用例:

using System; 
using System.Configuration; 
using System.Text; 
using IBM.XMS; 

namespace TestApp 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      //Setup unhandled exception "logging" 
      AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); 

      //Change this to your own needs! 
      string QueueManager = "CONTOSO"; 
      string Channel = "MYCOMPANY.CONTOSO.TCP"; 
      string Queue = "MYCOMPANY.REPORTQ"; 
      string HostIP = "192.168.1.29" 
      int Port = 1416; 

      //Create connection 
      var factoryfactory = XMSFactoryFactory.GetInstance(XMSC.CT_WMQ); 
      var connectionfactory = factoryfactory.CreateConnectionFactory(); 

      connectionfactory.SetStringProperty(XMSC.WMQ_QUEUE_MANAGER, QueueManager); 
      connectionfactory.SetStringProperty(XMSC.WMQ_HOST_NAME, HostIP); 
      connectionfactory.SetIntProperty(XMSC.WMQ_PORT, Port); 
      connectionfactory.SetStringProperty(XMSC.WMQ_CHANNEL, Channel); 
      connectionfactory.SetIntProperty(XMSC.WMQ_BROKER_VERSION, XMSC.WMQ_BROKER_V2); 
      connectionfactory.SetIntProperty(XMSC.WMQ_CONNECTION_MODE, XMSC.WMQ_CM_CLIENT_UNMANAGED); 

      var connection = connectionfactory.CreateConnection(); 
      connection.ExceptionListener = new ExceptionListener(OnXMSExceptionReceived); 

      //Create session 
      var session = connection.CreateSession(false, AcknowledgeMode.ClientAcknowledge); 

      //Create consumer 
      var queue = session.CreateQueue(string.Format("queue://{0}/{1}", QueueManager, Queue)); 
      queue.SetIntProperty(XMSC.WMQ_TARGET_CLIENT, XMSC.WMQ_TARGET_DEST_MQ); //Prevent automatic RFH (or JMS) headers in messages... 
      var consumer = session.CreateConsumer(queue); 
      consumer.MessageListener = new MessageListener(OnMessageReceived); //Messages received will be handled by OnMessageReceived 

      //Start the connection (which starts the consumer to listen etc.) 
      Console.WriteLine("Starting"); 
      connection.Start(); 
      Console.WriteLine("Started; press any key to stop"); 

      //Now we wait... 
      Console.ReadKey(); 

      //Tear down the connection 
      Console.WriteLine("Stopping"); 
      connection.Stop(); 
      Console.WriteLine("Stopped; press any key to end application"); 

      //Keep the console around 
      Console.ReadKey(); 
     } 

     private static void OnMessageReceived(IMessage message) 
     { 
      Console.WriteLine("Message received"); 
      if (message is IBytesMessage) 
      { 
       var bytesmsg = (IBytesMessage)message; 
       var data = new byte[bytesmsg.BodyLength]; 
       Console.WriteLine(Encoding.UTF8.GetString(data)); 
      } 
      else 
      { 
       //The message is not an IBytesMessage, check to see if it is a Feedback-type message 
       if (message.PropertyExists(XMSC.JMS_IBM_FEEDBACK)) 
       { 
        //Figure out which type of feedback message this is 
        int feedback = message.GetIntProperty(XMSC.JMS_IBM_FEEDBACK); 
        switch (feedback) 
        { 
         case MQC.MQFB_COA: 
          Console.WriteLine("COA received"); 
          break; 
         case MQC.MQFB_COD: 
          Console.WriteLine("COD received"); 
          break; 
         default: 
          //Unknown feedback type 
          Console.WriteLine("Unknown feedback"); 
          break; 
        } 
       } 
       else 
       { 
        //The message is not a feedback message; we don't know what this is so it's unexpected. 
        Console.WriteLine("Unexpected message received"); 
       } 
      } 

      Console.WriteLine("Acknowledging"); 
      message.Acknowledge(); 
      Console.WriteLine("Acknowledged"); 
     } 

     private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) 
     { 
      //Uh oh 
      Console.WriteLine("*** UnhandledException ***"); 
      Console.WriteLine((e.ExceptionObject as Exception).Message); 
      Console.WriteLine("******************************"); 
     } 

     private static void OnXMSExceptionReceived(Exception ex) 
     { 
      //Uh oh 
      Console.WriteLine("*** OnXMSExceptionReceived ***"); 
      Console.WriteLine(ex.Message); 
      Console.WriteLine("******************************"); 
     } 
    } 
} 

創建一個新的(控制檯)項目,加參考IBM.XMS.dll(C:\ Program Files(x86)\ IBM \ WebSphere MQ \ Tools \ Lib \ IBM.XMS.dll)並運行該項目。將任何消息放入報告隊列中,看看會發生什麼。

當連接到服務器V6一切都很好,在異常V7結果被拋出。

此外,我們試圖更新到2.1.0.1,但無濟於事...

編輯

這裏是我所看到的: Added a few more writelines but the crash is obvious

This is my trace log(對不起,不能因爲我的消息長度大於30000個字符),而here是一個更詳細的日誌(traceSpecification「all」而不是「debug」)。

我也嘗試切換(測試)應用到.NET V2.0.50727.5456但這並沒有幫助。

編輯

我似乎已經把範圍縮小到「空」的CoA和COD的;當使用MQRO_COA_WITH_DATA或MQRO_COA_WITH_FULL_DATA(與CoD相同)發送消息而不是MQRO_COA時,則不會發生CWSMQ0282E錯誤。所以XMS.Net似乎在CoA和CoD的空身上崩潰。我需要確認一些事情以確保它不是由我的項目中的其他內容造成的干擾,但我確信這是原因。

回答

0

至於我能確定這個例外,事實上,發生在「空」的CoA恩鱈魚。當郵件以發送MQRO_COA_WITH_DATA/MQRO_COD_WITH_DATA(或甚至更膨鬆MQRO_COA_WITH_FULL_DATA/MQRO_COD_WITH_FULL_DATA)異常不會發生。我們將向IBM提交一份「PMR」以確認。

0

的例外似乎是因爲接收到的消息沒有消息體。如果收到的消息是由於MQRO_COD或MQRC_COA選項(在發送原始消息時設置的)而沒有任何消息主體。當XMS嘗試沒有任何正文處理消息時,就會陷入困境。

我困惑的是如何使用MQ V6時工作。您可能要檢查,如果這是發送原始消息的應用程序已晚關閉改變。

同樣對於XMS處理任何消息,必須包含所需要的傳入消息JMS頭。 MQRO_COD/MQRO_COA由隊列管理器自動生成的,將不包含JMS頭。上面的代碼段

很少有其他建議:

1)的IPEndpoint實例並不真正需要。您可以簡單地將主機名或IP地址設置爲字符串和端口號作爲整數。

2)XMSC.RTT_BROKER_PING_INTERVAL連接WMQ時,不需要設置。

3)既然你已經使用AcknowledgeMode.AutoAcknowledge在創建會話,無需調用message.Acknowledge()OnMessageReceived方法。

+0

1)使用IPEndpoint是因爲我從一個更大的項目中解除了代碼;將爲測試應用程序變化,但不會改變什麼功能 2)將拆除,但也不會解決任何問題恐怕 3)這是不正確的解除;它實際上是ClientAcknowledge 我會回到您的文章的其餘部分。 – RobIII

+0

它在V6中工作正常; OnMessageReceived檢查正在接收什麼類型的消息(實際消息或報告(CoA/CoD))。我遺漏了OnMessageReceived的實現,因爲它甚至沒有被調用; XMS.Net *應該*調用函數,但它會崩潰,它會繞過來調用它。發送應用程序尚未更改(因爲我們自己的應用程序是發送方)。我將更新上面的代碼以反映您的建議更改並顯示更多的OnMessageReceived實現(即使它沒有關係,因爲它沒有被調用)。 – RobIII

+0

我已經更新了示例/測試代碼。在任何情況下,無論錯誤是什麼,您是否同意**至少**「收到消息」行應該寫入控制檯?我看到的是「...... blablablah Started,按任意鍵......」,然後** BOOM **(因爲隊列中有CoA/CoD)。當我手動刪除CoA/CoD消息時,應用程序可以正常啓動。使用MQ Explorer在隊列上放置「測試消息」可以很好地處理(「收到消息」,然後執行其餘部分)。再說一遍:這在V6中用得很好。 – RobIII