2012-08-06 56 views
0

我试图使用.NET WMQ API通过.NET应用程序使用通过WebSphere MQ(WebSphere MQ Server v7)发送的JMS消息。我正在使用WebSphere MQ客户端v7.5和amqmdnet.dll版本7.5.0.0。是否有可能在.NET WMQ API中读取JMSDeliveryMode属性?

阅读JMSDeliveryMode属性(Dlv属性为jms RFH2文件夹)时会出现一些非常奇怪的行为。 JMS应用程序发送的属性值(托管在WebSphere Application Server v7中的servlet)设置为Persistent(2),但我的.NET客户端始终读取1(表示Non_persistent)。我需要阅读正确的值,因为我的.NET应用程序作为路由器/转发器工作,并且必须以正确的配置转发消息。

我试着用RFHUtils来模拟JMS消息。当我将传递模式设置为1并将其发送给我的.NET客户端时,它将再次读取1,但如果我还在MQMD中更改了MQ消息的持久性,它将读取0.它看起来像JMSDeliveryMode中的值根本不使用,.NET客户端总是从Persistence属性读取值,但这是不正确的行为!这两个属性具有正确的值的不同范围:

JMSDeliveryMode正确值(从jms.jar):

  • 1 - DeliveryMode.NON_PERSISTENT
  • 2 - DeliveryMode.PERSISTENT

Persistence正确的值(从amqmdnet.dll):

  • 0 - MQC.MQPER_NOT_PERSISTENT
  • 1 - MQC.MQPER_PERSISTENT
  • 2 - MQC.MQPER_PERSISTENCE_AS_Q_DEF/MQC.MQPER_PERSISTENCE_AS_TOPIC_DEF

回答

0

这又是IBM的amqmdnet.dll错误。与.NET Reflector拆卸库和检查负责读取JMS属性代码(GetJmsPropertyMQMessage类的私有方法)后,我发现这一点:

if (name.Equals("JMSDeliveryMode")) 
{ 
    // Properties never contain the property with such name! 
    if (this.properties.ContainsKey("JMSDeliveryMode")) 
    { 
     ... 
    } 
    return this.Persistence; // Executes always 
} 

的问题是,properties集合从不包含任何财产与JMSDeliveryMode作为重点。 properties集合包含格式为的RFH2头文件RFH2Folder.RFH2PropertyNameJMSDeliveryMode的正确属性名称是jms.Dlv!有趣的是GetJmsHeader方法读取所有JMS属性,而所有其他属性在属性集合中搜索时使用正确的RFH2名称!

当我检查逆向操作时,情况更糟 - 专用方法SetJmsPropertyMQMessage类。设置JMSDeliveryMode包含此代码:

else if (name.Equals("JMSDeliveryMode")) 
{ 
    if (value is int) 
    { 
     int num2 = Convert.ToInt32(value); 
     switch (num2) 
     { 
      // Non persistent JMS message creates persistent MQ message 
      case 1: 
       this.Persistence = 1; 
       break; 
      // Invalid value for JMS delivery mode    
      case 0: 
       this.Persistence = 0; 
       break; 
      // Great if I try to create persistent JMS message I will 
      // get MQRC_PERSISTENCE_ERROR exception!    
      default: 
       base.throwNewMQException(2, 0x7ff); 
       break; 
     } 

     queue.Enqueue(num2); 
     // Correct RFH2 identifier is used 
     this.properties.Add("jms.Dlv", queue); 
    } 
    else 
    { 
     base.throwNewMQException(2, 0x9a9); 
    } 
} 

所以设置JMSDelivery模式要么火异常或设置无效坚持!以下是重现此问题的小测试:

[Test] 
public void PutAndGetMessageWithDeliveryMode() { 
    using (MQQueue queue = _queueManager.AccessQueue(TestQueue, MQC.MQOO_OUTPUT | MQC.MQOO_INPUT_AS_Q_DEF)) { 

     MQMessage message = new MQMessage(); 
     message.SetInt4Property("JMSDeliveryMode", 2); 
     message.WriteString("some string"); 
     message.Format = MQC.MQFMT_STRING; 

     queue.Put(message); 

     MQMessage readMessage = new MQMessage(); 
     queue.Get(readMessage); 

     Assert.AreEqual(2, readMessage.GetInt4Property("JMSDeliveryMode")); 

     queue.Close(); 
    } 
} 
0

MQ中持久性的值。NET是正确的,您可以与cmqc.h头文件进行比较,因为amqmdnet和C MQI都是MQ本地API。

0 - MQC.MQPER_NOT_PERSISTENT 
1 - MQC.MQPER_PERSISTENT 
2 - MQC.MQPER_PERSISTENCE_AS_Q_DEF/MQC.MQPER_PERSISTENCE_AS_TOPIC_DEF 

jms.jar DeliveryMode枚举定义了一个不同的值。我会想象MQ JMS实现将在内部适当地处理这个问题,并在MQMD和RFH2属性中设置正确的MQ特定值。

关于您使用RFH2Util的测试。在MQMD选项卡和JMS中设置的值可能不同。您可以在JMS选项卡中将DeliveryMode设置为1,并在MQMD选项卡中将Persistent Msg设置为No。当放置消息时,MQMD.Persistence将显示为0,并且JMSDeliveryMode将显示为1.我通过在MQ Explorer中查看消息来确认此值。 MQ .NET API只是给你从消息中得到的东西。据我所知RFHUtil是一个设置RFH属性的工具。它只是设置/获取RFH属性。它没有MQ JMS实现的智能。

在我看来,“JMSxxxx”属性最好由JMS实现来处理,而不是像MQ .NET这样的本地实现。

+0

MQ .NET API不给我我在消息中得到的东西。它甚至不允许我发送正确的值。如果MQ.NET API是“本地”实现,它应该给我一个完整的控制。我不明白为什么高层(JMS)在传输层(MQ)中直接硬编码的行为。这应该在一些桥梁中单独定义。 – 2012-08-06 18:28:49

相关问题