Claus Ibsen created CAMEL-24355:
-----------------------------------
Summary: NIOConverter.toByteArray throws BufferUnderflowException
when ByteBuffer has been fully read
Key: CAMEL-24355
URL: https://issues.apache.org/jira/browse/CAMEL-24355
Project: Camel
Issue Type: Bug
Reporter: Claus Ibsen
When a ByteBuffer has already been fully consumed (position == limit), the
NIOConverter.toByteArray() type converter throws a {{BufferUnderflowException}}.
This happens in practice with Kinesis KCL consumer: when a route error handler
tries to send the message to a dead letter queue (e.g. SQS), Camel attempts to
convert the ByteBuffer body to a String, which calls
{{NIOConverter.toByteArray()}}. Since the Kinesis KCL has already read the
buffer, the position is at the end and {{buffer.get(bArray)}} fails.
Stacktrace:
{code}
Caused by: java.nio.BufferUnderflowException
at java.base/java.nio.HeapByteBuffer.get(HeapByteBuffer.java:190)
at java.base/java.nio.ByteBuffer.get(ByteBuffer.java:855)
at org.apache.camel.converter.NIOConverter.toByteArray(NIOConverter.java:53)
at org.apache.camel.converter.NIOConverter.toString(NIOConverter.java:59)
{code}
The problem is in {{NIOConverter.toByteArray()}}:
{code:java}
public static byte[] toByteArray(ByteBuffer buffer) {
byte[] bArray = new byte[buffer.limit()];
buffer.get(bArray);
return bArray;
}
{code}
The method allocates an array of {{buffer.limit()}} bytes, but
{{buffer.get(bArray)}} reads from the current position. If the buffer has been
fully read (position == limit), there are 0 remaining bytes and the get() call
underflows.
The fix is to call {{rewind()}} before reading to reset position to 0 without
changing the limit.
Reported by Mark Wimpory on Zulip:
https://camel.zulipchat.com/#narrow/channel/257298-camel/topic/Camel.20error.20handler.20fails.20when.20processing.20a.20kinesis.20message/with/614575323
--
This message was sent by Atlassian Jira
(v8.20.10#820010)