2012-06-13 1 views
2

Мы используем XMS.Net для подключения к серверу Web7 WebSphere MQ; это всегда отлично работало с сервером 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; Я ожидаю, что они будут в очереди, и когда я выключу своего потребителя, слушая эти сообщения, все остальное прекрасно работает.

Я совершенно не знаю, что происходит ...

EDIT

Это минимальная TestCase:

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, но безрезультатно ...

EDIT

Вот что я вижу: 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, но это тоже не помогает.

EDIT

я, кажется, свели на «пустые» КоА и CoD-х; когда сообщения отправляются с MQRO_COA_WITH_DATA или MQRO_COA_WITH_FULL_DATA (то же самое для CoD), в отличие от MQRO_COA, тогда ошибка CWSMQ0282E не возникает. Таким образом, XMS.Net, похоже, падает на пустые тела для CoA и CoD. Мне нужно подтвердить некоторые вещи, чтобы убедиться, что это не вызвано тем, что другие вещи в моем проекте мешают, но я совершенно уверен, что это причина.

ответ

0

Насколько я могу определить это исключение, действительно, происходит на «пустом» CoA's Co Co. Когда сообщения отправляются с MQRO_COA_WITH_DATA/MQRO_COD_WITH_DATA (или даже более объемным MQRO_COA_WITH_FULL_DATA/MQRO_COD_WITH_FULL_DATA), исключение не возникает. Мы подтвердим подтверждение «PMR» с IBM.

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