mayur mohan created CAMEL-24553:
-----------------------------------
Summary: camel-support: getMandatoryBody() OOM guard — refuse huge
in-memory body conversion to String/byte[]
Key: CAMEL-24553
URL: https://issues.apache.org/jira/browse/CAMEL-24553
Project: Camel
Issue Type: Improvement
Reporter: mayur mohan
When the Splitter EIP attempts to evaluate a bean expression on a message with
a huge body (e.g. a multi-GB payload), the JVM dies with OutOfMemoryError
before any user-visible error is produced.
*Stack trace:*
{noformat}
org.apache.camel.CamelExecutionException: Exception occurred during execution
on the exchange: Exchange[F25AB2E9C97DF95-0000000000000001]
at
org.apache.camel.processor.MulticastProcessor.doProcess(MulticastProcessor.java:352)
at org.apache.camel.processor.Splitter.process(Splitter.java:158)
...
Caused by: java.lang.OutOfMemoryError: Required array length 2147483638 +
737144626 is too large
at
java.base/java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:582)
at java.base/java.lang.StringBuilder.append(StringBuilder.java:179)
at
org.apache.camel.InvalidPayloadException.<init>(InvalidPayloadException.java:39)
at
org.apache.camel.support.MessageSupport.getMandatoryBody(MessageSupport.java:125)
at
org.apache.camel.support.builder.ExpressionBuilder$33.evaluate(ExpressionBuilder.java:1028)
at
org.apache.camel.component.bean.MethodInfo$ParameterExpression.evaluate(MethodInfo.java:592)
at
org.apache.camel.processor.Splitter.createProcessorExchangePairs(Splitter.java:165)
at
org.apache.camel.processor.MulticastProcessor.doProcess(MulticastProcessor.java:347)
{noformat}
*Root cause:*
{{MessageSupport.getMandatoryBody(Class<T>)}} delegates directly to the type
converter without any size guard. When a route tries to convert a body that is
larger than {{Integer.MAX_VALUE}} characters to {{String}}, the type converter
attempts to allocate a {{StringBuilder}} of that size, causing an OOM that
kills the JVM.
*Fix:*
Add a pre-flight size check in {{MessageSupport.getMandatoryBody()}} that
refuses to convert bodies exceeding a configurable in-memory limit (default 256
MiB) to bulk types ({{String}}, {{byte[]}}, {{CharSequence}}). The check uses
the already-known length ({{CharSequence.length()}}, {{byte[].length}},
{{StreamCache.length()}}) without materialising the body, so there is zero
overhead for normal-sized payloads. When triggered, a clear
{{InvalidPayloadException}} with a diagnostic message is thrown instead of an
OOM.
The cap is overridable via system property {{camel.message.max-in-memory-body}}
(bytes).
This does NOT fix the root operational issue (splitting a multi-GB body as a
single String is inherently wrong) but prevents JVM death and provides an
actionable error message directing users to streaming split/tokenize.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)