You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@camel.apache.org by "Claus Ibsen (Jira)" <ji...@apache.org> on 2026/10/22 20:51:00 UTC

[jira] [Resolved] (CAMEL-25836) 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

     [ https://issues.apache.org/jira/browse/CAMEL-25836?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Claus Ibsen resolved CAMEL-25836.
---------------------------------
    Resolution: Fixed

> 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
>            Priority: Major
>             Fix For: 4.24.0
>
>
> 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
(v10.3.26#10030026)