0

我正在尝试使用.NET WMQ API 使用.NET 应用程序通过 WebSphere MQ (WebSphere MQ Server v7) 发送的 JMS 消息。我正在使用 WebSphere MQ Client v7.5 和 amqmdnet.dll 版本 7.5.0.0。

JMSDeliveryMode读取属性(Dlv来自jmsRFH2 文件夹的属性)时有一些非常奇怪的行为。JMS 应用程序(WebSphere Application Server v7 中托管的 servlet)发送的属性值设置为Persistent(2),但我的 .NET 客户端始终读取 1(这意味着Non_persistent)。我需要读取正确的值,因为我的 .NET 应用程序用作路由器/转发器,它必须转发具有正确配置的消息。

我尝试使用RFHUtils模拟 JMS 消息。当我将传递模式设置为 1 并将其发送到我的 .NET 客户端时,它再次读取 1,但如果我还在 MQMD 中更改 MQ 消息的持久性,它读取为 0。看起来JMSDeliveryMode根本没有使用 in 的值,并且 .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
4

2 回答 2

0

这又是 IBM 的 amqmdnet.dll 中的错误。在使用.NET Reflector反汇编库并检查负责读取 JMS 属性的代码(类GetJmsProperty的私有方法MQMessage)后,我发现:

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集合包含格式为 RFH2Folder.RFH2PropertyName的 RFH2 标头。正确的属性名称JMSDeliveryModejms.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();
    }
}
于 2012-08-06T16:26:56.757 回答
0

MQ .NET 中 Persistence 的值是正确的,您可以与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 中设置的值可能不同。No您可以在 JMS 选项卡中将 DeliveryMode 设置为 1,在 MQMD 选项卡中将Persistent Msg 设置为。放置消息时,MQMD.Persistence 将显示为0,而 JMSDeliveryMode 将显示为 1。我通过在 MQ Explorer 中查看消息确认了此值。MQ .NET API 只是为您提供它从消息中得到的信息。据我所知,RFHUtil 是一个设置 RFH 属性的工具。它只是设置/获取 RFH 属性。它没有 MQ JMS 实现的智能。

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

于 2012-08-06T18:05:35.400 回答