-
1. Re: IndexOutOfBoundsException when receiving binary messages with Stomp
mjustin Feb 17, 2010 10:18 AM (in response to mjustin)Hello,
I found that the exception occurs if the test data in the BytesMessage contains null bytes. In the StompTest.java unit test for BytesMessages, the test data is an array containing only non-null bytes:
byte[] data = new byte[] {1, 2, 3, 4};
So I modified my test to use the same byte sequence. The send from client to broker seems to work but when the broker sends the message to the client, it fails with an java.lang.NegativeArraySizeException:
java.lang.NegativeArraySizeException
at org.hornetq.core.protocol.stomp.StompSession.sendMessage(StompSession
.java:103)
at org.hornetq.core.server.impl.ServerConsumerImpl.deliverStandardMessag
e(ServerConsumerImpl.java:630)
at org.hornetq.core.server.impl.ServerConsumerImpl.handle(ServerConsumer
Impl.java:257)
at org.hornetq.core.server.impl.QueueImpl.handle(QueueImpl.java:1347)
at org.hornetq.core.server.impl.QueueImpl.directDeliver(QueueImpl.java:1
250)
at org.hornetq.core.server.impl.QueueImpl.add(QueueImpl.java:1307)
at org.hornetq.core.server.impl.QueueImpl.addLast(QueueImpl.java:231)
...So it looks like StompSession.java calculates the content length with a bad result:
int size = serverMessage.getEndOfBodyPosition() - buffer.readerIndex();
data = new byte[size];
Can I run the unit tests (StompTest.java) from command line or is it easier from an IDE?Regards,
Michael
-
2. Re: IndexOutOfBoundsException when receiving binary messages with Stomp
jmesnil Feb 17, 2010 10:35 AM (in response to mjustin)you can run StompTest from eclipse or from the command line:
./build.sh integration-tests -Dtest-mask=StompTest
-
3. Re: IndexOutOfBoundsException when receiving binary messages with Stomp
mjustin Feb 17, 2010 10:51 AM (in response to jmesnil)Hello Jeff,
null bytes in the test data break the unit test. Test data is:
byte[] data = new byte[] {1, 0, 0, 4};
Running the tests produces this error:
junit.framework.AssertionFailedError
at org.hornetq.tests.integration.stomp.StompTest.testSendMessageWithContentLength(StompTest.java:215)Line 215 is:
Assert.assertNotNull(message);
This is the same what I can see in the Delphi Stomp client.
So if I understand the source code correctly there is a problem with the Netty read(byte[] data) method when the input stream contains null bytes?
Michael
-
4. Re: IndexOutOfBoundsException when receiving binary messages with Stomp
jmesnil Feb 17, 2010 11:21 AM (in response to mjustin)I found the issue.
I'm using Netty's DelimiterBasedFrameDecoder to "delimit" a Stomp frame. It uses a NUL 0x00 byte as a delimiter.
However this will not work if you have NUL byte in the Stomp body.
I'll have to rewrite the decoder to fix this and make sure that if there is a content-length header, we read all the length
before creating the frame.
-
5. Re: IndexOutOfBoundsException when receiving binary messages with Stomp
timfox Feb 17, 2010 11:25 AM (in response to jmesnil)Best to use the
public int isReadyToHandle(HornetQBuffer buffer);
void handleBuffer(RemotingConnection connection, HornetQBuffer buffer);Methods on protocol manager to do this, instead of writing another framedecoder
-
6. Re: IndexOutOfBoundsException when receiving binary messages with Stomp
jmesnil Feb 17, 2010 11:46 AM (in response to timfox)timfox wrote:
Best to use the
public int isReadyToHandle(HornetQBuffer buffer);
void handleBuffer(RemotingConnection connection, HornetQBuffer buffer);Methods on protocol manager to do this, instead of writing another framedecoder
that was my 1st idea but in this case, it will not be simple or efficient.
I need to decode the buffer as it goes to be able to check if it has a "content-length" header or not.
If it has one, I know how many other bytes I need before handling the buffer.
Otherwise, I'll continue to read it until I encounter the first NUL byte.
I'll have decoded almost all the frame to know if I can handle it.
At this point, it'd be simpler to work with the decoded frame and pass it directly to the StompProtocolManager rather
than use a HornetQBuffer with all the needed bytes and decode it a 2nd time.
-
7. Re: IndexOutOfBoundsException when receiving binary messages with Stomp
timfox Feb 17, 2010 11:50 AM (in response to jmesnil)Why would it be less efficient?
You have to read the buffer anyway to see if it's ready.
I don't follow your logic here
-
8. Re: IndexOutOfBoundsException when receiving binary messages with Stomp
timfox Feb 17, 2010 11:51 AM (in response to timfox)You have to write the decoding logic *anyway*, the question is whether that logic is in a FrameDecoder or in the ProtocolManager.
It's cleaner to put it in the ProtocolManager since then all the protocol specific code is in one place.
-
9. Re: IndexOutOfBoundsException when receiving binary messages with Stomp
jmesnil Feb 17, 2010 11:56 AM (in response to timfox)My point was that using HornetQFrameDecoder, I'd have to decode the Frame twice in the ProtocolManager:
public int isReadyToHandle(HornetQBuffer buffer) { // decode almost all the frames to know its length return length; } public void handleBuffer(final RemotingConnection connection, final HornetQBuffer buffer) { // decode completely the frame a 2nd time StompFrame frame = decode(buffer); // work with the frame }
-
10. Re: IndexOutOfBoundsException when receiving binary messages with Stomp
timfox Feb 17, 2010 3:38 PM (in response to jmesnil)I'm still not with you, why would you need to decode the frame twice? -
11. Re: IndexOutOfBoundsException when receiving binary messages with Stomp
timfox Feb 17, 2010 3:44 PM (in response to timfox)Probably a better way to ask this question, is how would you write a FrameDecoder to do what you require?
BTW, this discussion should be on the dev forum