[英]XMS.Net 2.1.0.0/1 CWSMQ0282E
我们使用XMS.Net连接到WebSphere MQ服务器V7; 这对V6服务器一直运行良好,但由于“其他方”升级到V7,我们遇到了一些麻烦。 其中大部分都已修复,但现在我偶然发现了一个我无法解释的错误,也找不到任何关于:
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,但无济于事......
编辑
这就是我所看到的:
这是我的跟踪日志 (对不起,因为我的消息将超过30000个字符,所以不能在此添加) 这里有一个更详细的日志(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的空体上崩溃了。 我需要确认一些事情,以确保它不是由我的项目中的其他东西造成的干扰,但我很确定这是原因。
异常似乎是因为收到的消息没有消息正文。 如果收到的消息是由于MQRO_COD或MQRC_COA选项(在发送原始消息时设置)将没有任何消息体。 当XMS尝试处理没有任何正文的消息时,它就会遇到麻烦。
使用MQ v6时,我对这是如何工作感到困惑。 您可能想要检查发送原始邮件的应用程序是否已被更改。
此外,对于XMS处理任何消息,传入消息必须包含必需的JMS头。 MQRO_COD / MQRO_COA由队列管理器自动生成,不包含JMS头。
关于上面代码段的其他建议很少:
1) IPEndpoint
并不需要IPEndpoint
的实例。 您只需将主机名或IP地址设置为字符串,将端口号设置为整数即可。
2)连接WMQ时无需设置XMSC.RTT_BROKER_PING_INTERVAL
。
3)由于您在创建会话时使用了AcknowledgeMode.AutoAcknowledge
,因此无需在OnMessageReceived
方法中调用message.Acknowledge()
。
事实上,我可以确定这个例外情况发生在“空”的CoA的CoD上。 使用MQRO_COA_WITH_DATA
/ MQRO_COD_WITH_DATA
(或甚至更大的MQRO_COA_WITH_FULL_DATA
/ MQRO_COD_WITH_FULL_DATA
)发送消息时,不会发生异常。 我们将向IBM提交“PMR”以进行确认。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.