[ https://issues.apache.org/jira/browse/CAMEL-20889?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Luigi De Masi updated CAMEL-20889: ---------------------------------- Description: Having the following Camel route on Camel 2.x {code:java} from("timer:mytimer2?repeatCount=1&delay=1000") .routeId("generate-route-marshall") .streamCaching() .transform(constant("\{\"maskme\":\"json payload\"}")) .marshal().json(JsonLibrary.Jackson) .process(exchange -> { LOGGER.info("body class name -> " + exchange.getIn().getBody().getClass().getName()); LOGGER.info("consumed once using .getBody(String.class) -> " + exchange.getIn().getBody(String.class)); LOGGER.info("consumed twice using .getBody(String.class) -> " + exchange.getIn().getBody(String.class)); }) .to("jms:queue:INCOMING"); {code} Shows that the consumption of the message payload in the processor via {code:java} exchange.getIn().getBody(String.class));\{code} works as expected, as the body is shown twice on the logs, as follows. {code:java} body class name -> org.apache.camel.converter.stream.InputStreamCache consumed once using .getBody(String.class) -> "\{\"maskme\":\"json payload\"}" consumed twice using .getBody(String.class) -> "\{\"maskme\":\"json payload\"}" {code} But if you run this same route from Camel 3.x to the latest 4.x one, you will get the following output: {code:java} body class name -> org.apache.camel.converter.stream.InputStreamCache consumed once using .getBody(String.class) -> "\{\"maskme\":\"json payload\"}" consumed once using .getBody(String.class) -> {code} The problem is that on Camel 2.x, when ` exchange.getIn().getBody(String.class))` is called, the [org.apache.camel.converter.IOConverterOptimised|https://github.com/apache/camel/blob/camel-2.x/camel-core/src/main/java/org/apache/camel/converter/IOConverterOptimised.java] is triggered to convert the body from {{org.apache.camel.converter.stream.InputStreamCache}} to {{{}java.lang.String{}}}, which at the beginning of the convertion, [it reset the stream|https://github.com/apache/camel/blob/a05826ece32fbb8e2ba6df0e0ac2a3d5903f9572/camel-core/src/main/java/org/apache/camel/converter/IOConverterOptimised.java#L50]: {code:java|title=IOConverterOptimised.java} public final class IOConverterOptimised { private IOConverterOptimised() { } public static Object convertTo(final Class<?> type, final Exchange exchange, final Object value) throws Exception { Class fromType = value.getClass(); if (value instanceof StreamCache) { ((StreamCache)value).reset(); // <------ HERE } {code} >From Camel 3.x, IOConverterOptimised.java has been dropped, and >[org.apache.camel.impl.converter.CoreTypeConverterRegistry|] is used instead, >which doesn't reset the stream. A quick workaround is to reset the stream manually before trying to read it again: {code:java} LOGGER.info("body class name -> " + exchange.getIn().getBody().getClass().getName()); LOGGER.info("consumed once using .getBody(String.class) -> " + exchange.getIn().getBody(String.class)); exchange.getIn().getBody(InputStreamCache.class).reset(); LOGGER.info("consumed twice using .getBody(String.class) -> " + exchange.getIn().getBody(String.class)); {code} and you get this as output: {code:java} Started CamelArtemisApplication in 2.069 seconds (JVM running for 2.686) body class name -> org.apache.camel.converter.stream.InputStreamCache consumed once using .getBody(String.class) -> "{\"maskme\":\"json payload\"}" consumed twice using .getBody(String.class) -> "{\"maskme\":\"json payload\"}" {code} > Stream is not reset when Message.getBody(class) is invoked ans stream caching > is enabled > ---------------------------------------------------------------------------------------- > > Key: CAMEL-20889 > URL: https://issues.apache.org/jira/browse/CAMEL-20889 > Project: Camel > Issue Type: Bug > Components: came-core > Reporter: Luigi De Masi > Assignee: Luigi De Masi > Priority: Major > > Having the following Camel route on Camel 2.x > {code:java} > from("timer:mytimer2?repeatCount=1&delay=1000") > .routeId("generate-route-marshall") > .streamCaching() > .transform(constant("\{\"maskme\":\"json payload\"}")) > .marshal().json(JsonLibrary.Jackson) > .process(exchange -> > { > LOGGER.info("body class name -> " + > exchange.getIn().getBody().getClass().getName()); > LOGGER.info("consumed once using .getBody(String.class) -> " + > exchange.getIn().getBody(String.class)); > LOGGER.info("consumed twice using .getBody(String.class) -> " + > exchange.getIn().getBody(String.class)); > }) > .to("jms:queue:INCOMING"); > {code} > > Shows that the consumption of the message payload in the processor via > {code:java} > exchange.getIn().getBody(String.class));\{code} > works as expected, as the body is shown twice on the logs, as follows. > {code:java} > body class name -> org.apache.camel.converter.stream.InputStreamCache > consumed once using .getBody(String.class) -> "\{\"maskme\":\"json > payload\"}" > consumed twice using .getBody(String.class) -> "\{\"maskme\":\"json > payload\"}" > {code} > > But if you run this same route from Camel 3.x to the latest 4.x one, you > will get the following output: > {code:java} > body class name -> org.apache.camel.converter.stream.InputStreamCache > consumed once using .getBody(String.class) -> "\{\"maskme\":\"json > payload\"}" > consumed once using .getBody(String.class) -> > {code} > > The problem is that on Camel 2.x, when ` > exchange.getIn().getBody(String.class))` is called, the > [org.apache.camel.converter.IOConverterOptimised|https://github.com/apache/camel/blob/camel-2.x/camel-core/src/main/java/org/apache/camel/converter/IOConverterOptimised.java] > is triggered to convert the body from > {{org.apache.camel.converter.stream.InputStreamCache}} to > {{{}java.lang.String{}}}, which at the beginning of the convertion, [it reset > the > stream|https://github.com/apache/camel/blob/a05826ece32fbb8e2ba6df0e0ac2a3d5903f9572/camel-core/src/main/java/org/apache/camel/converter/IOConverterOptimised.java#L50]: > > {code:java|title=IOConverterOptimised.java} > public final class IOConverterOptimised { > private IOConverterOptimised() { > } > public static Object convertTo(final Class<?> type, final Exchange > exchange, final Object value) throws Exception { > Class fromType = value.getClass(); > if (value instanceof StreamCache) { > ((StreamCache)value).reset(); // <------ HERE > } > {code} > From Camel 3.x, IOConverterOptimised.java has been dropped, and > [org.apache.camel.impl.converter.CoreTypeConverterRegistry|] is used instead, > which doesn't reset the stream. > A quick workaround is to reset the stream manually before trying to read it > again: > {code:java} > LOGGER.info("body class name -> " + > exchange.getIn().getBody().getClass().getName()); > LOGGER.info("consumed once using .getBody(String.class) -> " > + exchange.getIn().getBody(String.class)); > exchange.getIn().getBody(InputStreamCache.class).reset(); > LOGGER.info("consumed twice using .getBody(String.class) -> " > + exchange.getIn().getBody(String.class)); > {code} > and you get this as output: > {code:java} > Started CamelArtemisApplication in 2.069 seconds (JVM running for 2.686) > body class name -> org.apache.camel.converter.stream.InputStreamCache > consumed once using .getBody(String.class) -> "{\"maskme\":\"json payload\"}" > consumed twice using .getBody(String.class) -> "{\"maskme\":\"json payload\"}" > {code} -- This message was sent by Atlassian Jira (v8.20.10#820010)