You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2026/07/14 09:36:17 UTC
(camel) 01/02: CAMEL-20141: camel-joor - Fix classpath for inline bean scripts and classloader cleanup
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch fix/CAMEL-20141
in repository https://gitbox.apache.org/repos/asf/camel.git
commit 539f441c31ae59a717514fde842f3cf5ad4496c5
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Tue Jul 14 09:54:37 2026 +0200
CAMEL-20141: camel-joor - Fix classpath for inline bean scripts and classloader cleanup
The CamelJoorClassLoader only included workDir/joor in its URLs, but
JavaRoutesBuilderLoader writes compiled .class files to workDir directly.
This caused inline bean scripts referencing user Java classes (e.g.
com.mycompany.CustomerBuilder) to fail with compilation errors.
Unified both compilers to use the same workDir, removing the outdated
/joor subdirectory. Also added classloader lifecycle management for
scripting classes: compiled classes are now registered and cleaned up
on reload to prevent accumulation.
Co-Authored-By: Claude Opus 4.6 <no...@anthropic.com>
Signed-off-by: Claus Ibsen <cl...@gmail.com>
---
.../apache/camel/language/joor/CamelJoorClassLoader.java | 3 +--
.../camel/language/joor/JoorScriptingCompiler.java | 16 +++++++++++++++-
2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/components/camel-joor/src/main/java/org/apache/camel/language/joor/CamelJoorClassLoader.java b/components/camel-joor/src/main/java/org/apache/camel/language/joor/CamelJoorClassLoader.java
index 06503e60b8b6..6d478d4f3ccc 100644
--- a/components/camel-joor/src/main/java/org/apache/camel/language/joor/CamelJoorClassLoader.java
+++ b/components/camel-joor/src/main/java/org/apache/camel/language/joor/CamelJoorClassLoader.java
@@ -53,8 +53,7 @@ public class CamelJoorClassLoader extends URLClassLoader {
CompileStrategy cs = camelContext.getCamelContextExtension().getContextPlugin(CompileStrategy.class);
if (cs != null && cs.getWorkDir() != null) {
try {
- File dir = new File(cs.getWorkDir() + "/joor");
- answer.add(dir.toURI().toURL());
+ answer.add(new File(cs.getWorkDir()).toURI().toURL());
} catch (MalformedURLException e) {
// ignore
}
diff --git a/components/camel-joor/src/main/java/org/apache/camel/language/joor/JoorScriptingCompiler.java b/components/camel-joor/src/main/java/org/apache/camel/language/joor/JoorScriptingCompiler.java
index c72d6f6db07f..ee33a0ff969b 100644
--- a/components/camel-joor/src/main/java/org/apache/camel/language/joor/JoorScriptingCompiler.java
+++ b/components/camel-joor/src/main/java/org/apache/camel/language/joor/JoorScriptingCompiler.java
@@ -45,6 +45,7 @@ public class JoorScriptingCompiler extends ServiceSupport implements StaticServi
private static final Logger LOG = LoggerFactory.getLogger(JoorScriptingCompiler.class);
private static final AtomicInteger UUID = new AtomicInteger();
+ private final Set<String> compiledClassNames = new LinkedHashSet<>();
private CamelContext camelContext;
private JavaJoorClassLoader classLoader;
private Set<String> imports = new TreeSet<>();
@@ -92,7 +93,7 @@ public class JoorScriptingCompiler extends ServiceSupport implements StaticServi
// use work dir for classloader as it writes compiled classes to disk
CompileStrategy cs = context.getCamelContextExtension().getContextPlugin(CompileStrategy.class);
if (cs != null && cs.getWorkDir() != null) {
- classLoader.setCompileDirectory(cs.getWorkDir() + "/joor");
+ classLoader.setCompileDirectory(cs.getWorkDir());
}
}
}
@@ -108,6 +109,15 @@ public class JoorScriptingCompiler extends ServiceSupport implements StaticServi
CamelContext camelContext, String script, Map<String, Object> bindings, boolean singleQuotes) {
StopWatch watch = new StopWatch();
+ // clean up previously compiled script classes to prevent classloader leak during reloads
+ if (classLoader != null && !compiledClassNames.isEmpty()) {
+ for (String old : compiledClassNames) {
+ LOG.debug("Removing old compiled class: {}", old);
+ classLoader.removeClass(old);
+ }
+ compiledClassNames.clear();
+ }
+
JoorScriptingMethod answer;
String className = nextFQN();
String code = evalCode(camelContext, className, script, bindings, singleQuotes);
@@ -131,6 +141,10 @@ public class JoorScriptingCompiler extends ServiceSupport implements StaticServi
if (clazz != null) {
LOG.debug("Compiled to Java class: {}", clazz);
answer = (JoorScriptingMethod) clazz.getConstructor(CamelContext.class).newInstance(camelContext);
+ // register compiled class for proper lifecycle management
+ byte[] byteCode = result.getByteCode(className);
+ classLoader.addClass(className, clazz, byteCode);
+ compiledClassNames.add(className);
} else {
answer = null;
}