解决the first blocker后,我能够转向更复杂的场景,我尝试从我的.NET组件往返发送自定义消息属性,将JMS消息发送到WebSphere Application Server v7中托管的消息驱动bean,并回复bean到.NET组件。此通信是通过WebSphere MQ v7完成的,但.NET使用WebSphere MQ Client v7.5和amqmdnet.dll v7.5.0.0(因为它修复了我对v7客户端的一些其他问题:例如this)。 / p>
我无法从.NET组件发送简单的布尔属性:
MQMessage message = new MQMessage();
message.SetBooleanProperty("TEST_BOOL", true);
queue.Put(message);
在消息驱动的bean中接收此类消息将失败:
[8/3/12 17:37:20:087 CEST] 0000003b SibMessage W [:] CWSJY0003W: JMSCC0110: An exception '
Message : com.ibm.msg.client.jms.DetailedMessageFormatException: JMSCMQ1050: The MQRFH2 header has an incorrect format. Received a message with a badly formed MQRFH2 header. Ensure that any non-JMS applications building messages with MQRFH2 headers create well-formed MQRFH2 headers.
Class : class com.ibm.msg.client.jms.DetailedMessageFormatException
Stack : sun.reflect.NativeConstructorAccessorImpl.newInstance0(NativeConstructorAccessorImpl.java:-2)
: sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:45)
: sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:39)
: java.lang.reflect.Constructor.newInstance(Constructor.java:515)
: com.ibm.msg.client.commonservices.j2se.NLSServices.createException(NLSServices.java:313)
: com.ibm.msg.client.commonservices.nls.NLSServices.createException(NLSServices.java:388)
: com.ibm.msg.client.wmq.common.internal.messages.WMQMessageBase._parseUsrFolder(WMQMessageBase.java:1984)
: com.ibm.msg.client.wmq.common.internal.messages.WMQReceiveMarshal.constructProviderMessageFromRFH2(WMQReceiveMarshal.java:402)
: com.ibm.msg.client.wmq.common.internal.messages.WMQReceiveMarshal.constructProviderMessageFromProperties(WMQReceiveMarshal.java:191)
: com.ibm.msg.client.wmq.common.internal.messages.WMQReceiveMarshal.createProviderMessage(WMQReceiveMarshal.java:467)
: com.ibm.msg.client.wmq.common.internal.messages.WMQReceiveMarshal.exportProviderMessage(WMQReceiveMarshal.java:627)
: com.ibm.msg.client.wmq.internal.WMQConsumerShadow.getMsg(WMQConsumerShadow.java:1318)
: com.ibm.msg.client.wmq.internal.WMQConsumerShadow.getMsg(WMQConsumerShadow.java:1208)
: com.ibm.msg.client.wmq.internal.WMQSyncConsumerShadow.receive(WMQSyncConsumerShadow.java:366)
: com.ibm.msg.client.wmq.internal.WMQSession.loadMessageReference(WMQSession.java:1318)
: com.ibm.msg.client.jms.internal.JmsSessionImpl.consume(JmsSessionImpl.java:2940)
: com.ibm.msg.client.jms.internal.JmsSessionImpl.run(JmsSessionImpl.java:2631)
: com.ibm.mq.jms.MQSession.run(MQSession.java:862)
: com.ibm.mq.connector.inbound.WorkImpl.run(WorkImpl.java:265)
: com.ibm.ejs.j2c.work.WorkProxy.run(WorkProxy.java:399)
: com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1604)
Caused by [1] --> Message : com.ibm.msg.client.jms.DetailedMessageFormatException: JMSCMQ0008: WebSphere MQ classes for JMS attempts to use a data type not supported by a message or attempts to read data in the wrong type. Wrong data types used to read message property types. Check that the message received and the properties to be read are of the type expected.
Class : class com.ibm.msg.client.jms.DetailedMessageFormatException
Stack : sun.reflect.NativeConstructorAccessorImpl.newInstance0(NativeConstructorAccessorImpl.java:-2)
: sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:45)
: sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:39)
: java.lang.reflect.Constructor.newInstance(Constructor.java:515)
: com.ibm.msg.client.commonservices.j2se.NLSServices.createException(NLSServices.java:313)
: com.ibm.msg.client.commonservices.nls.NLSServices.createException(NLSServices.java:388)
: com.ibm.msg.client.wmq.common.internal.messages.WMQMessageUtils.deformatTypedElement(WMQMessageUtils.java:306)
: com.ibm.msg.client.wmq.common.internal.messages.WMQMessageUtils.deformatElement(WMQMessageUtils.java:414)
: com.ibm.msg.client.wmq.common.internal.messages.WMQMessageBase._parseUsrFolder(WMQMessageBase.java:1963)
: com.ibm.msg.client.wmq.common.internal.messages.WMQReceiveMarshal.constructProviderMessageFromRFH2(WMQReceiveMarshal.java:402)
: com.ibm.msg.client.wmq.common.internal.messages.WMQReceiveMarshal.constructProviderMessageFromProperties(WMQReceiveMarshal.java:191)
: com.ibm.msg.client.wmq.common.internal.messages.WMQReceiveMarshal.createProviderMessage(WMQReceiveMarshal.java:467)
: com.ibm.msg.client.wmq.common.internal.messages.WMQReceiveMarshal.exportProviderMessage(WMQReceiveMarshal.java:627)
: com.ibm.msg.client.wmq.internal.WMQConsumerShadow.getMsg(WMQConsumerShadow.java:1318)
: com.ibm.msg.client.wmq.internal.WMQConsumerShadow.getMsg(WMQConsumerShadow.java:1208)
: com.ibm.msg.client.wmq.internal.WMQSyncConsumerShadow.receive(WMQSyncConsumerShadow.java:366)
: com.ibm.msg.client.wmq.internal.WMQSession.loadMessageReference(WMQSession.java:1318)
: com.ibm.msg.client.jms.internal.JmsSessionImpl.consume(JmsSessionImpl.java:2940)
: com.ibm.msg.client.jms.internal.JmsSessionImpl.run(JmsSessionImpl.java:2631)
: com.ibm.mq.jms.MQSession.run(MQSession.java:862)
: com.ibm.mq.connector.inbound.WorkImpl.run(WorkImpl.java:265)
: com.ibm.ejs.j2c.work.WorkProxy.run(WorkProxy.java:399)
: com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1604)
' was caught while processing a message for delivery to a message driven bean.
答案 0 :(得分:1)
我使用RFHUtils来获取.NET组件发送的消息。 usr
RFH2文件夹包含以下定义:
TEST_BOOL(dt='boolean')=True
如果我将值更改为1
而不是True
并使用RFHUtils发送消息,则会正确处理。解压缩的资源适配器(我正在使用JD-GUI)也表明它只需要布尔JMS属性的0
和1
值。
static Object deformatTypedElement(int datatype, String value)
throws JMSException
{
Object result = null;
switch (datatype) {
...
case 1:
if (value.equals("1")) {
result = new Boolean(true);
}
else if (value.equals("0")) {
result = new Boolean(false);
}
else {
JMSException je = (JMSException)NLSServices.createException("JMSCMQ0008", null); // Line 306 - BOOM!
throw je;
}
// There is also no break here but I think it is a problem of decompiler
...
}
}
.NET的amqmdnet.dll库的反编译代码(我正在使用.NET Reflector)表明它在将布尔值传递给消息之前不会转换它们。它只使用值ToString()
:
internal class MQMarshalMessageForPut : MQBaseObject
{
...
private void SetContent(RFH2Folder element, object value)
{
...
if (value is bool)
{
element.SetContent(value.ToString(), 1);
}
...
}
}
但ToString
类型bool
会返回True
或False
!
消息驱动bean对.NET应用程序的响应没有任何问题,因为GetBoolProperty
已准备好使用True
和False
字符串以及0
和{ {1}}值。
1
我认为这是IBM的amqmdnet.dll库中的一个错误。
答案 1 :(得分:1)
这是一个错误,正确的行为应该允许应用程序使用布尔值的编程语言表示。在这种情况下,.NET是" true / false"和JMS为1/0。 MQ应该转换两个应用程序之间的布尔值。
现在已经修复了。
答案 2 :(得分:0)
布尔True
和False
有不同的定义。有些语言将True表示为1,将False表示为0,其中一些语言将False定义为0,将任何非零(包括1和-1)定义为True。有些像Ruby将True定义为0.因此,不能说True为1而False为0.因此MQ .NET和Java API将布尔值设置为True
和False
本身并且接收应用程序可以根据他们的语言细节来解释它。
但是在消息接收期间,MQ .NET和Java API会将1识别为True,将0识别为false。这更像是一个可用性点。发送消息时同样不能应用,必须始终设置一致的值,有时不能设置1和有时设置为真。