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 2022/04/27 09:10:01 UTC

[camel] branch main updated (b5dbfd07482 -> 8b087db4e76)

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


    from b5dbfd07482 CAMEL-17832: camel-grpc - Upgrade to Netty 4.1.76 (#7501)
     new e2b6a8fba07 CAMEL-18014: camel-java-dsl - Allow to capture compiled byte code
     new 8b087db4e76 CAMEL-17998: camel-jbang - fat-jar command

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../org/apache/camel/main/fatjar/FatJarMain.java   |  6 ++-
 .../dsl/java/joor/ClassRoutesBuilderLoader.java    |  5 ++
 .../camel/dsl/java/joor/CompilationUnit.java       |  8 ++-
 .../dsl/java/joor/JavaRoutesBuilderLoader.java     | 28 ++++++-----
 .../apache/camel/dsl/java/joor/MultiCompile.java   |  4 ++
 .../camel/dsl/jbang/core/commands/FatJar.java      | 21 +++++++-
 .../apache/camel/dsl/jbang/core/commands/Run.java  | 13 +++--
 .../camel/main/AnnotationDependencyInjection.java  | 23 +++++++--
 .../apache/camel/main/JavaJoorPostCompiler.java    | 57 ++++++++++++++++++++++
 .../java/org/apache/camel/main/KameletMain.java    |  5 ++
 10 files changed, 145 insertions(+), 25 deletions(-)
 create mode 100644 dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/JavaJoorPostCompiler.java


[camel] 01/02: CAMEL-18014: camel-java-dsl - Allow to capture compiled byte code

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git

commit e2b6a8fba07528be45025aad5bf698d4a62e6951
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Apr 27 06:20:58 2022 +0200

    CAMEL-18014: camel-java-dsl - Allow to capture compiled byte code
---
 .../camel/dsl/java/joor/CompilationUnit.java       |  8 +++-
 .../dsl/java/joor/JavaRoutesBuilderLoader.java     | 28 +++++++------
 .../apache/camel/dsl/java/joor/MultiCompile.java   |  4 ++
 .../camel/main/AnnotationDependencyInjection.java  | 11 ++++-
 .../apache/camel/main/JavaJoorPostCompiler.java    | 48 ++++++++++++++++++++++
 .../java/org/apache/camel/main/KameletMain.java    |  2 +
 6 files changed, 86 insertions(+), 15 deletions(-)

diff --git a/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/CompilationUnit.java b/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/CompilationUnit.java
index e6b489ad029..a9c8ccf9b1a 100644
--- a/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/CompilationUnit.java
+++ b/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/CompilationUnit.java
@@ -36,8 +36,12 @@ public class CompilationUnit {
         private final Map<String, byte[]> compiled = new LinkedHashMap<>();
 
         void addResult(String className, Class<?> clazz, byte[] byteCode) {
-            classes.put(className, clazz);
-            compiled.put(className, byteCode);
+            if (clazz != null && !classes.containsKey(className)) {
+                classes.put(className, clazz);
+            }
+            if (byteCode != null && !compiled.containsKey(className)) {
+                compiled.put(className, byteCode);
+            }
         }
 
         /**
diff --git a/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/JavaRoutesBuilderLoader.java b/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/JavaRoutesBuilderLoader.java
index 9e87733f52a..b679be54486 100644
--- a/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/JavaRoutesBuilderLoader.java
+++ b/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/JavaRoutesBuilderLoader.java
@@ -85,20 +85,24 @@ public class JavaRoutesBuilderLoader extends ExtendedRouteBuilderLoaderSupport {
         }
 
         for (String className : result.getClassNames()) {
+            Object obj = null;
+
             Class<?> clazz = result.getClass(className);
-            Object obj;
-            try {
-                // requires a default no-arg constructor otherwise we skip the class
-                obj = getCamelContext().getInjector().newInstance(clazz);
-            } catch (Exception e) {
-                LOG.debug("Compiled class: " + className + " must have a default no-arg constructor. Skipping.");
-                continue;
-            }
-            LOG.debug("Compiled: {} -> {}", className, obj);
+            if (clazz != null) {
+                try {
+                    // requires a default no-arg constructor otherwise we skip the class
+                    obj = getCamelContext().getInjector().newInstance(clazz);
+                } catch (Exception e) {
+                    LOG.debug("Compiled class: " + className + " must have a default no-arg constructor. Skipping.");
+                }
+                if (obj != null) {
+                    LOG.debug("Compiled: {} -> {}", className, obj);
 
-            // inject context and resource
-            CamelContextAware.trySetCamelContext(obj, getCamelContext());
-            ResourceAware.trySetResource(obj, nameToResource.get(className));
+                    // inject context and resource
+                    CamelContextAware.trySetCamelContext(obj, getCamelContext());
+                    ResourceAware.trySetResource(obj, nameToResource.get(className));
+                }
+            }
 
             // support custom annotation scanning post compilation
             // such as to register custom beans, type converters, etc.
diff --git a/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/MultiCompile.java b/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/MultiCompile.java
index b2443958a7f..a9d1ccbeca9 100644
--- a/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/MultiCompile.java
+++ b/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/MultiCompile.java
@@ -160,6 +160,8 @@ public final class MultiCompile {
                     if (clazz != null) {
                         result.addResult(className, clazz, byteCodes.get(className));
                     }
+                    // we may have compiled additional classes that the className is using, so add these as result as well
+                    byteCodes.forEach((cn, bc) -> result.addResult(cn, null, bc));
                 } else {
                     // Otherwise, use an arbitrary class loader. This approach doesn't allow for
                     // loading private-access interfaces in the compiled class's type hierarchy
@@ -176,6 +178,8 @@ public final class MultiCompile {
                     if (clazz != null) {
                         result.addResult(className, clazz, byteCodes.get(className));
                     }
+                    // we may have compiled additional classes that the className is using, so add these as result as well
+                    byteCodes.forEach((cn, bc) -> result.addResult(cn, null, bc));
                 }
             }
 
diff --git a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/AnnotationDependencyInjection.java b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/AnnotationDependencyInjection.java
index 5c3d4a40199..a181c2cf5e1 100644
--- a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/AnnotationDependencyInjection.java
+++ b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/AnnotationDependencyInjection.java
@@ -100,6 +100,10 @@ public final class AnnotationDependencyInjection {
 
         @Override
         public void postCompile(CamelContext camelContext, String name, Class<?> clazz, byte[] byteCode, Object instance) throws Exception {
+            if (instance == null) {
+                return;
+            }
+
             BindToRegistry bir = instance.getClass().getAnnotation(BindToRegistry.class);
             Configuration cfg = instance.getClass().getAnnotation(Configuration.class);
             if (bir != null || cfg != null || instance instanceof CamelConfiguration) {
@@ -131,11 +135,13 @@ public final class AnnotationDependencyInjection {
 
         @Override
         public void postCompile(CamelContext camelContext, String name, Class<?> clazz, byte[] byteCode, Object instance) throws Exception {
+            if (instance == null) {
+                return;
+            }
             // @Component and @Service are the same
             Component comp = clazz.getAnnotation(Component.class);
             Service service = clazz.getAnnotation(Service.class);
             if (comp != null || service != null) {
-                CamelBeanPostProcessor bpp = camelContext.adapt(ExtendedCamelContext.class).getBeanPostProcessor();
                 if (comp != null && ObjectHelper.isNotEmpty(comp.value())) {
                     name = comp.value();
                 } else if (service != null && ObjectHelper.isNotEmpty(service.value())) {
@@ -203,6 +209,9 @@ public final class AnnotationDependencyInjection {
 
         @Override
         public void postCompile(CamelContext camelContext, String name, Class<?> clazz, byte[] byteCode, Object instance) throws Exception {
+            if (instance == null) {
+                return;
+            }
             // @ApplicationScoped and @Singleton are considered the same
             ApplicationScoped as = clazz.getAnnotation(ApplicationScoped.class);
             Singleton ss = clazz.getAnnotation(Singleton.class);
diff --git a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/JavaJoorPostCompiler.java b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/JavaJoorPostCompiler.java
new file mode 100644
index 00000000000..606336cbe03
--- /dev/null
+++ b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/JavaJoorPostCompiler.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.main;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.dsl.support.CompilePostProcessor;
+import org.apache.camel.spi.Registry;
+import org.apache.camel.util.IOHelper;
+
+import java.io.FileOutputStream;
+
+public class JavaJoorPostCompiler {
+
+    // TODO: add option to turn this on|off, and configure disk location
+
+    public static void initJavaJoorPostCompiler(CamelContext context) {
+        Registry registry = context.getRegistry();
+
+        registry.bind("JavaJoorPostCompiler", new ByteCodeCompilePostProcessor());
+    }
+
+    private static class ByteCodeCompilePostProcessor implements CompilePostProcessor {
+
+        @Override
+        public void postCompile(CamelContext camelContext, String name, Class<?> clazz, byte[] byteCode, Object instance) throws Exception {
+            if (byteCode != null) {
+                FileOutputStream fos = new FileOutputStream("." + name + ".class", false);
+                fos.write(byteCode);
+                IOHelper.close(fos);
+            }
+        }
+    }
+
+}
diff --git a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
index be6e9247e6b..902663286ff 100644
--- a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
+++ b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
@@ -198,6 +198,8 @@ public class KameletMain extends MainCommandLineSupport {
         answer.setLoadHealthChecks(true);
         // annotation based dependency injection for camel/spring/quarkus annotations in DSLs and Java beans
         AnnotationDependencyInjection.initAnnotationBasedDependencyInjection(answer);
+        // java-dsl post compiler to save compilation to disk
+        JavaJoorPostCompiler.initJavaJoorPostCompiler(answer);
 
         // embed HTTP server if port is specified
         Object port = getInitialProperties().get("camel.jbang.platform-http.port");


[camel] 02/02: CAMEL-17998: camel-jbang - fat-jar command

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 8b087db4e76cf60d013aba9deb6c79fd51de426d
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Apr 27 11:09:42 2022 +0200

    CAMEL-17998: camel-jbang - fat-jar command
---
 .../org/apache/camel/main/fatjar/FatJarMain.java   |  6 ++++-
 .../dsl/java/joor/ClassRoutesBuilderLoader.java    |  5 ++++
 .../camel/dsl/jbang/core/commands/FatJar.java      | 21 +++++++++++++--
 .../apache/camel/dsl/jbang/core/commands/Run.java  | 13 ++++++---
 .../camel/main/AnnotationDependencyInjection.java  | 12 ++++++---
 .../apache/camel/main/JavaJoorPostCompiler.java    | 31 ++++++++++++++--------
 .../java/org/apache/camel/main/KameletMain.java    |  5 +++-
 7 files changed, 71 insertions(+), 22 deletions(-)

diff --git a/dsl/camel-fatjar-main/src/main/java/org/apache/camel/main/fatjar/FatJarMain.java b/dsl/camel-fatjar-main/src/main/java/org/apache/camel/main/fatjar/FatJarMain.java
index 66af107fe00..5323961235c 100644
--- a/dsl/camel-fatjar-main/src/main/java/org/apache/camel/main/fatjar/FatJarMain.java
+++ b/dsl/camel-fatjar-main/src/main/java/org/apache/camel/main/fatjar/FatJarMain.java
@@ -68,8 +68,12 @@ public class FatJarMain extends KameletMain {
 
         // setup configurations
         for (String key : prop.stringPropertyNames()) {
-            String value = prop.getProperty(key);
+            if ("camel.main.routesReloadEnabled".equals(key)) {
+                // skip reload as this is not possible in fat-jar mode
+                continue;
+            }
             if (key.startsWith("camel.")) {
+                String value = prop.getProperty(key);
                 addInitialProperty(key, value);
             }
         }
diff --git a/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/ClassRoutesBuilderLoader.java b/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/ClassRoutesBuilderLoader.java
index 0b9a10d0d0c..29075318e78 100644
--- a/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/ClassRoutesBuilderLoader.java
+++ b/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/ClassRoutesBuilderLoader.java
@@ -31,6 +31,7 @@ import org.apache.camel.dsl.support.ExtendedRouteBuilderLoaderSupport;
 import org.apache.camel.spi.Resource;
 import org.apache.camel.spi.ResourceAware;
 import org.apache.camel.spi.annotations.RoutesLoader;
+import org.apache.camel.util.StringHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -98,6 +99,10 @@ public class ClassRoutesBuilderLoader extends ExtendedRouteBuilderLoaderSupport
 
     private static String asClassName(Resource resource) {
         String className = resource.getLocation();
+        if (className.contains(":")) {
+            // remove scheme such as classpath:foo.class
+            className = StringHelper.after(className, ":");
+        }
         className = className.replace('/', '.');
         if (className.endsWith(".class")) {
             className = className.substring(0, className.length() - 6);
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/FatJar.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/FatJar.java
index 5e24cc8f95b..a1d7ac13d95 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/FatJar.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/FatJar.java
@@ -65,7 +65,7 @@ class FatJar implements Callable<Integer> {
 
     @Override
     public Integer call() throws Exception {
-        File settings = new File(Run.RUN_SETTINGS_FILE);
+        File settings = new File(Run.WORK_DIR + "/" + Run.RUN_SETTINGS_FILE);
         if (!settings.exists()) {
             System.out.println("Run Camel first to generate dependency file");
             return 0;
@@ -83,6 +83,8 @@ class FatJar implements Callable<Integer> {
         target = new File("target/camel-app/classes");
         target.mkdirs();
         copySourceFiles(settings, target);
+        // work sources
+        copyWorkFiles(Run.WORK_DIR, target);
         // settings
         copySettings(settings);
         // log4j configuration
@@ -151,7 +153,7 @@ class FatJar implements Callable<Integer> {
 
     private void copySettings(File settings) throws Exception {
         // the settings file itself
-        File target = new File("target/camel-app/classes", Run.RUN_SETTINGS_FILE.substring(1));
+        File target = new File("target/camel-app/classes", Run.RUN_SETTINGS_FILE);
 
         // need to adjust file: scheme to classpath as the files are now embedded in the fat-jar directly
         List<String> lines = Files.readAllLines(settings.toPath());
@@ -169,7 +171,9 @@ class FatJar implements Callable<Integer> {
     private static String fileToClasspath(String line, String key) {
         String value = StringHelper.after(line, key + "=");
         if (value != null) {
+            // file:foo.java is compiled to .class so we need to replace it
             value = value.replaceAll("file:", "classpath:");
+            value = value.replaceAll(".java", ".class");
             line = key + "=" + value;
         }
         return line;
@@ -288,6 +292,19 @@ class FatJar implements Callable<Integer> {
         }
     }
 
+    private void copyWorkFiles(String work, File target) throws Exception {
+        File[] files = new File(work).listFiles();
+        if (files != null) {
+            for (File source : files) {
+                if (source.getName().equals(Run.RUN_SETTINGS_FILE)) {
+                    continue; // skip this file as we copy this specially
+                }
+                File out = new File(target, source.getName());
+                safeCopy(source, out, true);
+            }
+        }
+    }
+
     private void copyJars(URI[] uris, File target) throws Exception {
         for (URI u : uris) {
             File f = new File(u.toURL().getFile());
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java
index d59489f1098..7527fb299f6 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java
@@ -49,7 +49,8 @@ import static org.apache.camel.dsl.jbang.core.commands.GitHubHelper.fetchGithubU
 @Command(name = "run", description = "Run Camel")
 class Run implements Callable<Integer> {
 
-    public static final String RUN_SETTINGS_FILE = ".camel-jbang-run.properties";
+    public static final String WORK_DIR = ".camel-jbang";
+    public static final String RUN_SETTINGS_FILE = "camel-jbang-run.properties";
 
     private static final String[] ACCEPTED_FILE_EXT
             = new String[] { "properties", "java", "groovy", "js", "jsh", "kts", "xml", "yaml" };
@@ -164,7 +165,11 @@ class Run implements Callable<Integer> {
     }
 
     private int run() throws Exception {
-        settings = new FileOutputStream(RUN_SETTINGS_FILE, false);
+        File work = new File(WORK_DIR);
+        FileUtil.removeDir(work);
+        work.mkdirs();
+
+        settings = new FileOutputStream(WORK_DIR + "/" + RUN_SETTINGS_FILE, false);
 
         // configure logging first
         if (logging) {
@@ -201,14 +206,16 @@ class Run implements Callable<Integer> {
         main.addInitialProperty("camel.main.shutdownTimeout", "5");
         writeSettings("camel.main.shutdownTimeout", "5");
 
-        // turn off lightweight if we have routes reload enabled
         main.addInitialProperty("camel.main.routesReloadEnabled", reload ? "true" : "false");
+        writeSettings("camel.main.routesReloadEnabled", reload ? "true" : "false");
         main.addInitialProperty("camel.main.sourceLocationEnabled", "true");
         writeSettings("camel.main.sourceLocationEnabled", "true");
         main.addInitialProperty("camel.main.tracing", trace ? "true" : "false");
         writeSettings("camel.main.tracing", trace ? "true" : "false");
         main.addInitialProperty("camel.main.modeline", modeline ? "true" : "false");
         writeSettings("camel.main.modeline", modeline ? "true" : "false");
+        main.addInitialProperty("camel.jbang.work-directory", WORK_DIR);
+        writeSettings("camel.jbang.work-directory", WORK_DIR);
 
         // command line arguments
         if (property != null) {
diff --git a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/AnnotationDependencyInjection.java b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/AnnotationDependencyInjection.java
index a181c2cf5e1..368b7abafea 100644
--- a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/AnnotationDependencyInjection.java
+++ b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/AnnotationDependencyInjection.java
@@ -77,7 +77,8 @@ public final class AnnotationDependencyInjection {
     private static class TypeConverterCompilePostProcessor implements CompilePostProcessor {
 
         @Override
-        public void postCompile(CamelContext camelContext, String name, Class<?> clazz, byte[] byteCode, Object instance) throws Exception {
+        public void postCompile(CamelContext camelContext, String name, Class<?> clazz, byte[] byteCode, Object instance)
+                throws Exception {
             if (clazz.isAnnotationPresent(Converter.class)) {
                 TypeConverterRegistry tcr = camelContext.getTypeConverterRegistry();
                 TypeConverterExists exists = tcr.getTypeConverterExists();
@@ -99,7 +100,8 @@ public final class AnnotationDependencyInjection {
     private static class BindToRegistryCompilePostProcessor implements CompilePostProcessor {
 
         @Override
-        public void postCompile(CamelContext camelContext, String name, Class<?> clazz, byte[] byteCode, Object instance) throws Exception {
+        public void postCompile(CamelContext camelContext, String name, Class<?> clazz, byte[] byteCode, Object instance)
+                throws Exception {
             if (instance == null) {
                 return;
             }
@@ -134,7 +136,8 @@ public final class AnnotationDependencyInjection {
     private static class SpringAnnotationCompilePostProcessor implements CompilePostProcessor {
 
         @Override
-        public void postCompile(CamelContext camelContext, String name, Class<?> clazz, byte[] byteCode, Object instance) throws Exception {
+        public void postCompile(CamelContext camelContext, String name, Class<?> clazz, byte[] byteCode, Object instance)
+                throws Exception {
             if (instance == null) {
                 return;
             }
@@ -208,7 +211,8 @@ public final class AnnotationDependencyInjection {
     private static class QuarkusAnnotationCompilePostProcessor implements CompilePostProcessor {
 
         @Override
-        public void postCompile(CamelContext camelContext, String name, Class<?> clazz, byte[] byteCode, Object instance) throws Exception {
+        public void postCompile(CamelContext camelContext, String name, Class<?> clazz, byte[] byteCode, Object instance)
+                throws Exception {
             if (instance == null) {
                 return;
             }
diff --git a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/JavaJoorPostCompiler.java b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/JavaJoorPostCompiler.java
index 606336cbe03..ab6fbbead17 100644
--- a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/JavaJoorPostCompiler.java
+++ b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/JavaJoorPostCompiler.java
@@ -16,29 +16,38 @@
  */
 package org.apache.camel.main;
 
+import java.io.File;
+import java.io.FileOutputStream;
+
 import org.apache.camel.CamelContext;
 import org.apache.camel.dsl.support.CompilePostProcessor;
-import org.apache.camel.spi.Registry;
 import org.apache.camel.util.IOHelper;
 
-import java.io.FileOutputStream;
-
+/**
+ * Post compiler for java-joor-dsl that stores the compiled .java sources as .class files to disk.
+ */
 public class JavaJoorPostCompiler {
 
-    // TODO: add option to turn this on|off, and configure disk location
-
-    public static void initJavaJoorPostCompiler(CamelContext context) {
-        Registry registry = context.getRegistry();
-
-        registry.bind("JavaJoorPostCompiler", new ByteCodeCompilePostProcessor());
+    public static void initJavaJoorPostCompiler(CamelContext context, String outputDirectory) {
+        context.getRegistry().bind("JavaJoorDslPostCompiler", new ByteCodeCompilePostProcessor(outputDirectory));
     }
 
     private static class ByteCodeCompilePostProcessor implements CompilePostProcessor {
 
+        private final String outputDirectory;
+
+        public ByteCodeCompilePostProcessor(String outputDirectory) {
+            this.outputDirectory = outputDirectory;
+        }
+
         @Override
-        public void postCompile(CamelContext camelContext, String name, Class<?> clazz, byte[] byteCode, Object instance) throws Exception {
+        public void postCompile(CamelContext camelContext, String name, Class<?> clazz, byte[] byteCode, Object instance)
+                throws Exception {
             if (byteCode != null) {
-                FileOutputStream fos = new FileOutputStream("." + name + ".class", false);
+                // create work-dir if needed
+                new File(outputDirectory).mkdirs();
+                // write to disk
+                FileOutputStream fos = new FileOutputStream(outputDirectory + "/" + name + ".class", false);
                 fos.write(byteCode);
                 IOHelper.close(fos);
             }
diff --git a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
index 902663286ff..00418848231 100644
--- a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
+++ b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
@@ -199,7 +199,10 @@ public class KameletMain extends MainCommandLineSupport {
         // annotation based dependency injection for camel/spring/quarkus annotations in DSLs and Java beans
         AnnotationDependencyInjection.initAnnotationBasedDependencyInjection(answer);
         // java-dsl post compiler to save compilation to disk
-        JavaJoorPostCompiler.initJavaJoorPostCompiler(answer);
+        String dir = (String) getInitialProperties().get("camel.jbang.work-directory");
+        if (dir != null) {
+            JavaJoorPostCompiler.initJavaJoorPostCompiler(answer, dir);
+        }
 
         // embed HTTP server if port is specified
         Object port = getInitialProperties().get("camel.jbang.platform-http.port");