shashank created CAMEL-25836:
--------------------------------

             Summary: camel-jte - a template given in the CamelJteTemplate 
header is compiled again for every exchange, and each compiled class and its 
files are kept for ever
                 Key: CAMEL-25836
                 URL: https://issues.apache.org/jira/browse/CAMEL-25836
             Project: Camel
          Issue Type: Bug
            Reporter: shashank
            Assignee: shashank


With {{allowTemplateFromHeader=true}}, a template given in the 
{{CamelJteTemplate}} header is handed to the JTE engine under the exchange id 
as its name ({{JteEndpoint.onExchange}}, main 20cdb309f7d0):

{code:java}
if (codeResolver != null) {
    name = exchange.getExchangeId();
    codeResolver.addTemplateFromHeader(name, content);
}
...
template.render(name, dataModel, buffer);
{code}

The runtime JTE engine ({{TemplateEngine.create}}, used unless 
{{preCompile=true}}) compiles each template name it has not seen into a Java 
class. It keeps that class in its template cache, keyed by the name, and writes 
the generated source and class files to the work directory ({{workDir}}, 
default {{jte-classes}}). As every exchange has a new id, every exchange 
compiles the same template again (javac in the routing thread). The engine also 
keeps one more class in memory (template cache and metaspace) and leaves two 
more files on disk. Nothing ever removes them while the CamelContext runs. A 
route that renders a header template for every message grows without bound 
until the JVM runs out of metaspace or heap, or the disk fills.

*Fix*: name a header template after a SHA-256 digest of its content 
({{header-<hex>}}). The same template is compiled once and reused, and the 
engine keeps one class per distinct template text, as it does for the templates 
of the endpoint URI. Templates given by resource URI or in the endpoint are not 
affected.

*Tests*: new {{JteTemplateFromHeaderCompiledOnceTest}} (2 tests) counts the 
compiled classes in the work directory. {{sameTemplateIsCompiledOnce}} (20 
exchanges, one template) fails on main: {{expected: <1> but was: <20>}}. 
{{eachDistinctTemplateIsCompiledOnce}} (two templates, 10 exchanges each) fails 
on main: {{expected: <2> but was: <20>}}. Both pass with the fix, and the 
rendered output of every exchange is checked. camel-jte unit tests with the 
fix: 6 run, 0 failures.

*How it was found*: a search for per-exchange keys (exchange ids) put into 
long-lived maps across the components, looking for unbounded leaks, then a read 
of the JTE 3.2.4 runtime ({{TemplateEngine.templateCache}}, keyed by template 
name), then the JUnit test above.

*Affected*: main, camel-4.23.x, camel-4.22.x, camel-4.18.x, camel-4.14.x and 
camel-4.10.x (the same {{name = exchange.getExchangeId()}}; read, not run). 
Only routes that enable {{allowTemplateFromHeader}} and set the 
{{CamelJteTemplate}} header are affected.

_Filed with Claude Code on behalf of allthingssecurity._




--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to