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)

Reply via email to