6 Replies Latest reply on Jul 30, 2014 1:01 AM by pitpalme

    Help reading ClientMessage body

    pitpalme

      Hello,

       

      I'm trying to write a DLQ-browsing application to be able to inspect messages moved to DLQ for it's contents, so I can decide whether another delivery attempts might succeed (e.g. max attempts have been exceeded because of temporary resource problem) or if message should be deleted straight ahead, because of invalid content.

       

      Using "session.createConsumer(queue, filter, true)" and ".receiveImmediate()" on the resulting object reference I get a "ClientMessage".

      I'm printing several attributes, but when trying to dump the body I'm stuck.

       

      message.getBodyBuffer().readString()

       

      on a message with "getType() == Message.TEXT_TYPE" results in

       

      java.lang.IndexOutOfBoundsException: Not enough readable bytes - Need 1006649088, maximum is 14710

       

      Doing a hex dump of

       

      HornetQBuffer buf = message.getBodyBuffer();

      int tmpLen = Math.min(message.getBodySize(), 64);

      byte[] tmpBody = new byte[tmpLen];

      buf.getBytes(buf.readerIndex(), tmpBody, 0, tmpBody.length);

      hexdump(tmpBody, tmpBody.length);

       

      outputs

       

      0000: 0100 0039 7A3C 003F 0078 006D 006C 0020 0076 0065 0072 0073 0069 006F 006E 003D  ...9z<.?.x.m.l. .v.e.r.s.i.o.n.=

      0001: 0022 0031 002E 0030 0022 0020 0065 006E 0063 006F 0064 0069 006E 0067 003D 0022  .".1...0.". .e.n.c.o.d.i.n.g.=."

       

      How to read that message body correctly?

       

      Thanks in advance,

      Peter

        • 1. Re: Help reading ClientMessage body
          jbertram

          The message body is just an array of bytes so how you read the body will be dictated by how it was written.

          1 of 1 people found this helpful
          • 2. Re: Help reading ClientMessage body
            pitpalme

            Thanks Justin for trying to help.

             

            The messages have been sent as JMS text message.

            Usually, i.e. when ending up in DLQ, those messages are delivered to a JMS MDB, that effectively reads the body using "javax.jms.TextMessage#getText".

             

            So my first attempt was to simply read the bytes and create a string.

            Unluckily, as can be seen from hex dump in my original post, there's some "garbage" preceding the text itself.

            I guess HornetQ - as JMS implementation within JBoss - put those bytes there and would remove it when used in JMS context.

             

            So I thought "org.hornetq.api.core.HornetQBuffer#readString" would be correct.

            Alas ... Although test messages, explicitly created using HornetQ core API on my development environment, could be read this way, JMS messages couldn't.

             

            I meanwhile figured "org.hornetq.api.core.HornetQBuffer#readNullableSimpleString" results in usable output for those messages.

            Sadly it doesn't work for messages sent using STOMP, simply because it's of type "org.hornetq.api.core.Message#BYTES_TYPE".

             

            I guess it's a different topic, why STOMP delivered (text) messages are byte messages.

            But: Is there a way to determine is a message of type "org.hornetq.api.core.Message#TEXT_TYPE" originates from JMS API part or HornetQ API, so I can either use "HornetQBuffer#readString" or "HornetQBuffer#readNullableSimpleString" without try 'n error and exception catching?

             

            Thanks,

            Peter

            • 3. Re: Help reading ClientMessage body
              jbertram

              The messages have been sent as JMS text message.

              Usually, i.e. when ending up in DLQ, those messages are delivered to a JMS MDB, that effectively reads the body using "javax.jms.TextMessage#getText".

              If that's the case then why not simply use the HornetQ JMS consumer to get the message and read it the same way?

               

              BTW, you can see how the HornetQ javax.jms.TextMessage implementation works here.  As you can see, the text is clearly encoded using org.hornetq.api.core.HornetQBuffer.writeNullableSimpleString() which is why it can be decoded using org.hornetq.api.core.HornetQBuffer.readNullableSimpleString().

               

              Sadly it doesn't work for messages sent using STOMP, simply because it's of type "org.hornetq.api.core.Message#BYTES_TYPE".

              Take a look at the documentation and org.hornetq.core.protocol.stomp.VersionedStompFrameHandler.onSend() for more insight here.

               

              But: Is there a way to determine is a message of type "org.hornetq.api.core.Message#TEXT_TYPE" originates from JMS API part or HornetQ API, so I can either use "HornetQBuffer#readString" or "HornetQBuffer#readNullableSimpleString" without try 'n error and exception catching?

              To my knowledge, there's no way to directly tell the difference between a message created via the JMS API vs. the core API.

              • 4. Re: Re: Help reading ClientMessage body
                pitpalme

                The messages have been sent as JMS text message.

                Usually, i.e. when ending up in DLQ, those messages are delivered to a JMS MDB, that effectively reads the body using "javax.jms.TextMessage#getText".

                If that's the case then why not simply use the HornetQ JMS consumer to get the message and read it the same way?

                Well, actually I'm writing a tool for our production team. If monitoring detects messages in DLQ I want them to be able to SSH to the server and "peek a boo" to tell developers of the business application the messages were intended for about their observations. Additionally they'll be able to tell what message to move back into which queue (by filtering by messageID or original address.

                I haven't seen how to connect to HornetQ inside JBoss using hornetq-jms-client beside JBoss remoting and I wanted to use the most performant way, i.e. port 5445.

                BTW, you can see how the HornetQ javax.jms.TextMessage implementation works here.

                Have found it exactly when writing my previous answer and therefore seen "writeNullableSimpleString()" and took the guess to use "readNullableSimpleString()"

                Sadly it doesn't work for messages sent using STOMP, simply because it's of type "org.hornetq.api.core.Message#BYTES_TYPE".

                Take a look at the documentation and org.hornetq.core.protocol.stomp.VersionedStompFrameHandler.onSend() for more insight here.

                Thanks for the link :) I'll have a look and see what options I do have ...

                But: Is there a way to determine is a message of type "org.hornetq.api.core.Message#TEXT_TYPE" originates from JMS API part or HornetQ API, so I can either use "HornetQBuffer#readString" or "HornetQBuffer#readNullableSimpleString" without try 'n error and exception catching?

                To my knowledge, there's no way to directly tell the difference between a message created via the JMS API vs. the core API.

                Sad Maybe I can make use of "getByte()" and evaluate the result to determine, whether "readNullableSimpleString()" or "readString()" (with it's two internal "readInt()" calls that seems to lead into trouble on JMS messages) should succeed ...

                 

                Thanks for all your help!

                 

                Regards,

                Peter

                • 5. Re: Help reading ClientMessage body
                  jbertram

                  I haven't seen how to connect to HornetQ inside JBoss using hornetq-jms-client beside JBoss remoting and I wanted to use the most performant way, i.e. port 5445.

                  Take a look at the documentation.

                  1 of 1 people found this helpful
                  • 6. Re: Help reading ClientMessage body
                    pitpalme

                    Justin Bertram schrieb:

                     

                    I haven't seen how to connect to HornetQ inside JBoss using hornetq-jms-client beside JBoss remoting and I wanted to use the most performant way, i.e. port 5445.

                    Take a look at the documentation.

                    That was far too easy

                    I must have been blinded by the core API to not see jms-client being able to connect through netty.

                     

                    Thanks once more