这又是 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 标头。正确的属性名称JMSDeliveryMode
是jms.Dlv
! 有趣的是GetJmsHeader
,在属性集合中搜索时,方法会读取所有 JMS 属性,并且所有其他属性都使用正确的 RFH2 名称!
当我检查反向操作时情况更糟 -类中的私有方法SetJmsProperty
。MQMessage
设置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();
}
}