¿Cómo enviar la propiedad booleana del usuario desde la API del cliente .MNET de WMQ a JMS?

Después de resolver el primer bloqueador, pude avanzar hacia un escenario más complejo e intenté hacer una vuelta a las propiedades de mensajes personalizados desde mi componente .NET enviando mensajes JMS a bean controlado por mensajes alojado en WebSphere Application Server v7 y el bean respondiendo de nuevo al componente .NET . Esta comunicación se realiza a través de WebSphere MQ v7, pero .NET usa WebSphere MQ Client v7.5 y amqmdnet.dll v7.5.0.0 (porque soluciona algunos otros problemas que tuve con el cliente v7: por ejemplo, esto).

No puedo enviar una propiedad booleana simple desde el componente .NET:

MQMessage message = new MQMessage();
message.SetBooleanProperty("TEST_BOOL", true);
queue.Put(message);

Recibir dicho mensaje en bean controlado por mensaje fallará con:

[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.
Respuesta 1

Solía RFHUtils hacer llegar el mensaje enviado por mi componente .NET. usrLa carpeta RFH2 contiene esta definición:

TEST_BOOL(dt='boolean')=True

Si cambio el valor a en 1lugar de Trueenviar el mensaje usando RFHUtils, se procesa correctamente. El adaptador de recursos descompilados (estoy usando JD-GUI ) también mostró que solo espera 0y 1valores para propiedades booleanas de JMS.

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
       ...
    }
}

El código descompilado de la biblioteca amqmdnet.dll para .NET (estoy usando .NET Reflector ) mostró que no convierte valores booleanos antes de pasarlos al mensaje. Simplemente usa ToString()en el valor:

internal class MQMarshalMessageForPut : MQBaseObject
{
   ...

   private void SetContent(RFH2Folder element, object value)
   {
       ...

       if (value is bool)
       {
           element.SetContent(value.ToString(), 1);
       }

       ...
    }
} 

Pero ToStringen booltipo devuelve Trueo False!

La respuesta de mensaje llevado de vuelta a frijol aplicación .NET funciona sin ningún problema, ya que GetBoolPropertyestá preparado para trabajar con ambos Truey Falsecuerdas y 0y 1valores.

private bool ParseBoolean(object obj) 
{
    ...

    if ((string.Compare(strA, "true", true) == 0) || (strA == "1"))
    {
        strA = bool.TrueString;
    }
    else if ((string.Compare(strA, "false", true) == 0) || (strA == "0"))
    {
        strA = bool.FalseString;
    }


    ...
}

Creo que esto es un error en la biblioteca amqmdnet.dll de IBM.

Respuesta: 2

Esto es un error, el comportamiento correcto debería permitir que las aplicaciones usen la representación de lenguajes de programación de un valor booleano. En este caso .NET es "verdadero / falso" y JMS es 1/0. MQ debería convertir el valor booleano entre las dos aplicaciones.

Esto ahora ha sido arreglado.

Respuesta: 3

Generé algunos javadocs, se ve bastante bien, incluso puedo incluir ejemplos / ejemplos de código en línea. Sin embargo, no se ve muy bien en dispositivos móviles: aquí están las configuraciones de complementos que estoy usando: <plugin & ...

Tengo un AuthenticationHandler que amplía ChannelHandlerAdapter y en el canal Lea un cheque si el usuario es válido. Si es así, agrego un nuevo controlador (ServerHandler) para recibir todos los demás mensajes. ctx.pipeline (...

Estoy intentando obtener un método de superclase para que se ejecute en métodos / campos de subclase cuando la subclase lo llama. Por ejemplo, public class CoffeeMachine () {protected int cost = 3; protegido int ...

¿Ya sea que JdbcDaoSupport # getConnection () establezca una conexión nueva o simplemente obtenga la conexión del grupo?