You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by al...@apache.org on 2023/01/18 21:17:47 UTC

[camel-quarkus] 01/02: Ref #4413: JavaShell DSL support

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

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

commit fed063f7987319ac3dc41c99980ff6fd5282255f
Author: Nicolas Filotto <nf...@talend.com>
AuthorDate: Tue Jan 17 15:17:16 2023 +0100

    Ref #4413: JavaShell DSL support
---
 catalog/pom.xml                                    |  13 ++
 docs/modules/ROOT/examples/others/jsh-dsl.yml      |  13 ++
 docs/modules/ROOT/nav.adoc                         |   1 +
 .../ROOT/pages/reference/extensions/jsh-dsl.adoc   |  45 +++++++
 .../dsl}/deployment/pom.xml                        |   8 +-
 .../dsl/deployment/DslGeneratedClassBuildItem.java |  16 ++-
 .../dsl/deployment/DslSupportProcessor.java        | 117 +++++++++++++++++
 .../deployment => extensions-support/dsl}/pom.xml  |  40 ++----
 .../dsl/runtime}/pom.xml                           |  26 ++--
 .../quarkus/support/dsl/runtime/DslRecorder.java   |  27 ++--
 .../dsl/runtime/RoutesBuilderConfigurer.java       |  17 +--
 .../main/resources/META-INF/quarkus-extension.yaml |  27 ++++
 extensions-support/pom.xml                         |   1 +
 extensions/groovy-dsl/deployment/pom.xml           |   4 +
 .../dsl/groovy/deployment/GroovyDslProcessor.java  |  58 ++-------
 extensions/groovy-dsl/runtime/pom.xml              |   4 +
 .../quarkus/dsl/groovy/runtime/Configurer.java     |   4 +-
 .../dsl/groovy/runtime/GroovyDslRecorder.java      |  49 -------
 .../{kotlin-dsl => jsh-dsl}/deployment/pom.xml     |  18 +--
 .../dsl/jsh/deployment/JshDslProcessor.java}       | 142 +++++++--------------
 extensions/jsh-dsl/pom.xml                         |  39 ++++++
 extensions/{kotlin-dsl => jsh-dsl}/runtime/pom.xml |  23 ++--
 .../camel/quarkus/dsl/jsh}/runtime/Configurer.java |  21 +--
 .../graal/SubstituteJshRoutesBuilderLoader.java}   |  29 ++---
 .../main/resources/META-INF/quarkus-extension.yaml |  31 +++++
 extensions/kotlin-dsl/deployment/pom.xml           |   4 +
 .../dsl/kotlin/deployment/KotlinDslProcessor.java  |  59 ++-------
 extensions/kotlin-dsl/runtime/pom.xml              |   4 +
 .../quarkus/dsl/kotlin/runtime/Configurer.java     |   4 +-
 extensions/pom.xml                                 |   1 +
 integration-tests/jsh-dsl/pom.xml                  | 129 +++++++++++++++++++
 .../camel/quarkus/dsl/jsh/JshDslResource.java      |  82 ++++++++++++
 .../src/main/resources/application.properties      |  21 +++
 .../jsh-dsl/src/main/resources/routes/MyRoute.jsh  |  16 +--
 .../org/apache/camel/quarkus/dsl/jsh/JshDslIT.java |  14 +-
 .../apache/camel/quarkus/dsl/jsh/JshDslTest.java   |  59 +++++++++
 integration-tests/pom.xml                          |   1 +
 pom.xml                                            |   1 +
 poms/bom/pom.xml                                   |  25 ++++
 poms/bom/src/main/generated/flattened-full-pom.xml |  25 ++++
 .../src/main/generated/flattened-reduced-pom.xml   |  25 ++++
 .../generated/flattened-reduced-verbose-pom.xml    |  25 ++++
 tooling/scripts/test-categories.yaml               |   1 +
 43 files changed, 890 insertions(+), 379 deletions(-)

diff --git a/catalog/pom.xml b/catalog/pom.xml
index 64b71cd9ad..5b741c77b4 100644
--- a/catalog/pom.xml
+++ b/catalog/pom.xml
@@ -2190,6 +2190,19 @@
                 </exclusion>
             </exclusions>
         </dependency>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-jsh-dsl</artifactId>
+            <version>${project.version}</version>
+            <type>pom</type>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>*</groupId>
+                    <artifactId>*</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
         <dependency>
             <groupId>org.apache.camel.quarkus</groupId>
             <artifactId>camel-quarkus-jslt</artifactId>
diff --git a/docs/modules/ROOT/examples/others/jsh-dsl.yml b/docs/modules/ROOT/examples/others/jsh-dsl.yml
new file mode 100644
index 0000000000..7c5fd07803
--- /dev/null
+++ b/docs/modules/ROOT/examples/others/jsh-dsl.yml
@@ -0,0 +1,13 @@
+# Do not edit directly!
+# This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
+cqArtifactId: camel-quarkus-jsh-dsl
+cqArtifactIdBase: jsh-dsl
+cqNativeSupported: true
+cqStatus: Stable
+cqDeprecated: false
+cqJvmSince: 2.16.0
+cqNativeSince: 2.16.0
+cqCamelPartName: jsh-dsl
+cqCamelPartTitle: JavaShell DSL
+cqCamelPartDescription: Camel DSL with JavaShell
+cqExtensionPageTitle: JavaShell DSL
diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc
index 6f65282373..067639ebce 100644
--- a/docs/modules/ROOT/nav.adoc
+++ b/docs/modules/ROOT/nav.adoc
@@ -185,6 +185,7 @@
 *** xref:reference/extensions/jasypt.adoc[Jasypt]
 *** xref:reference/extensions/java-joor-dsl.adoc[Java jOOR DSL]
 *** xref:reference/extensions/js-dsl.adoc[JavaScript DSL]
+*** xref:reference/extensions/jsh-dsl.adoc[JavaShell DSL]
 *** xref:reference/extensions/jfr.adoc[Jfr]
 *** xref:reference/extensions/jira.adoc[Jira]
 *** xref:reference/extensions/johnzon.adoc[Johnzon]
diff --git a/docs/modules/ROOT/pages/reference/extensions/jsh-dsl.adoc b/docs/modules/ROOT/pages/reference/extensions/jsh-dsl.adoc
new file mode 100644
index 0000000000..34346168a1
--- /dev/null
+++ b/docs/modules/ROOT/pages/reference/extensions/jsh-dsl.adoc
@@ -0,0 +1,45 @@
+// Do not edit directly!
+// This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
+[id="extensions-jsh-dsl"]
+= JavaShell DSL
+:linkattrs:
+:cq-artifact-id: camel-quarkus-jsh-dsl
+:cq-native-supported: true
+:cq-status: Stable
+:cq-status-deprecation: Stable
+:cq-description: Camel DSL with JavaShell
+:cq-deprecated: false
+:cq-jvm-since: 2.16.0
+:cq-native-since: 2.16.0
+
+ifeval::[{doc-show-badges} == true]
+[.badges]
+[.badge-key]##JVM since##[.badge-supported]##2.16.0## [.badge-key]##Native since##[.badge-supported]##2.16.0##
+endif::[]
+
+Camel DSL with JavaShell
+
+[id="extensions-jsh-dsl-whats-inside"]
+== What's inside
+
+* xref:{cq-camel-components}:others:jsh-dsl.adoc[JavaShell DSL]
+
+Please refer to the above link for usage and configuration details.
+
+[id="extensions-jsh-dsl-maven-coordinates"]
+== Maven coordinates
+
+https://{link-quarkus-code-generator}/?extension-search=camel-quarkus-jsh-dsl[Create a new project with this extension on {link-quarkus-code-generator}, window="_blank"]
+
+Or add the coordinates to your existing project:
+
+[source,xml]
+----
+<dependency>
+    <groupId>org.apache.camel.quarkus</groupId>
+    <artifactId>camel-quarkus-jsh-dsl</artifactId>
+</dependency>
+----
+ifeval::[{doc-show-user-guide-link} == true]
+Check the xref:user-guide/index.adoc[User guide] for more information about writing Camel Quarkus applications.
+endif::[]
diff --git a/extensions/groovy-dsl/deployment/pom.xml b/extensions-support/dsl/deployment/pom.xml
similarity index 89%
copy from extensions/groovy-dsl/deployment/pom.xml
copy to extensions-support/dsl/deployment/pom.xml
index c8b563e0c9..ed5d21b9b1 100644
--- a/extensions/groovy-dsl/deployment/pom.xml
+++ b/extensions-support/dsl/deployment/pom.xml
@@ -21,13 +21,13 @@
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>org.apache.camel.quarkus</groupId>
-        <artifactId>camel-quarkus-groovy-dsl-parent</artifactId>
+        <artifactId>camel-quarkus-support-dsl-parent</artifactId>
         <version>2.16.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 
-    <artifactId>camel-quarkus-groovy-dsl-deployment</artifactId>
-    <name>Camel Quarkus :: Groovy DSL :: Deployment</name>
+    <artifactId>camel-quarkus-support-dsl-deployment</artifactId>
+    <name>Camel Quarkus :: Support :: DSL :: Deployment</name>
 
     <dependencies>
         <dependency>
@@ -36,7 +36,7 @@
         </dependency>
         <dependency>
             <groupId>org.apache.camel.quarkus</groupId>
-            <artifactId>camel-quarkus-groovy-dsl</artifactId>
+            <artifactId>camel-quarkus-support-dsl</artifactId>
         </dependency>
     </dependencies>
 
diff --git a/extensions/groovy-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/groovy/deployment/GroovyGeneratedClassBuildItem.java b/extensions-support/dsl/deployment/src/main/java/org/apache/camel/quarkus/support/dsl/deployment/DslGeneratedClassBuildItem.java
similarity index 65%
rename from extensions/groovy-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/groovy/deployment/GroovyGeneratedClassBuildItem.java
rename to extensions-support/dsl/deployment/src/main/java/org/apache/camel/quarkus/support/dsl/deployment/DslGeneratedClassBuildItem.java
index 2dbe334a7f..dc6b2a2023 100644
--- a/extensions/groovy-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/groovy/deployment/GroovyGeneratedClassBuildItem.java
+++ b/extensions-support/dsl/deployment/src/main/java/org/apache/camel/quarkus/support/dsl/deployment/DslGeneratedClassBuildItem.java
@@ -14,18 +14,24 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.quarkus.dsl.groovy.deployment;
+package org.apache.camel.quarkus.support.dsl.deployment;
 
 import io.quarkus.builder.item.MultiBuildItem;
 
-public final class GroovyGeneratedClassBuildItem extends MultiBuildItem {
+public final class DslGeneratedClassBuildItem extends MultiBuildItem {
 
     final String name;
     final String location;
+    final boolean instantiateWithCamelContext;
 
-    public GroovyGeneratedClassBuildItem(String name, String location) {
+    public DslGeneratedClassBuildItem(String name, String location) {
+        this(name, location, false);
+    }
+
+    public DslGeneratedClassBuildItem(String name, String location, boolean instantiateWithCamelContext) {
         this.name = name;
         this.location = location;
+        this.instantiateWithCamelContext = instantiateWithCamelContext;
     }
 
     public String getName() {
@@ -35,4 +41,8 @@ public final class GroovyGeneratedClassBuildItem extends MultiBuildItem {
     public String getLocation() {
         return location;
     }
+
+    public boolean isInstantiateWithCamelContext() {
+        return instantiateWithCamelContext;
+    }
 }
diff --git a/extensions-support/dsl/deployment/src/main/java/org/apache/camel/quarkus/support/dsl/deployment/DslSupportProcessor.java b/extensions-support/dsl/deployment/src/main/java/org/apache/camel/quarkus/support/dsl/deployment/DslSupportProcessor.java
new file mode 100644
index 0000000000..b2ac19fb29
--- /dev/null
+++ b/extensions-support/dsl/deployment/src/main/java/org/apache/camel/quarkus/support/dsl/deployment/DslSupportProcessor.java
@@ -0,0 +1,117 @@
+/*
+ * 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.quarkus.support.dsl.deployment;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import io.quarkus.deployment.annotations.BuildStep;
+import io.quarkus.deployment.annotations.ExecutionTime;
+import io.quarkus.deployment.annotations.Record;
+import io.quarkus.deployment.pkg.steps.NativeBuild;
+import io.quarkus.runtime.RuntimeValue;
+import org.apache.camel.CamelContext;
+import org.apache.camel.quarkus.core.deployment.spi.CamelContextBuildItem;
+import org.apache.camel.quarkus.support.dsl.runtime.DslRecorder;
+import org.apache.camel.spi.Resource;
+import org.apache.camel.util.FileUtil;
+
+public class DslSupportProcessor {
+
+    private static final Pattern IMPORT_PATTERN = Pattern.compile("import .*");
+    public static final String CLASS_EXT = ".class";
+
+    @BuildStep(onlyIf = NativeBuild.class)
+    @Record(value = ExecutionTime.STATIC_INIT)
+    void registerRoutesBuilder(List<DslGeneratedClassBuildItem> classes,
+            CamelContextBuildItem context,
+            DslRecorder recorder) throws Exception {
+        RuntimeValue<CamelContext> camelContext = context.getCamelContext();
+        for (DslGeneratedClassBuildItem clazz : classes) {
+            recorder.registerRoutesBuilder(camelContext, clazz.getName(), clazz.getLocation(),
+                    clazz.isInstantiateWithCamelContext());
+        }
+    }
+
+    /**
+     * @param  resource the resource from which the name is extracted.
+     * @return          gives a name based on the location of the resource that can be used as a class name.
+     */
+    public static String determineName(Resource resource) {
+        String str = FileUtil.onlyName(resource.getLocation(), true);
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0, length = str.length(); i < length; i++) {
+            char c = str.charAt(i);
+            if ((i == 0 && Character.isJavaIdentifierStart(c)) || (i > 0 && Character.isJavaIdentifierPart(c))) {
+                sb.append(c);
+            } else {
+                sb.append((int) c);
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * @param  contentResource the content of the resource from which the imports must be extracted.
+     * @return                 the result of the extraction containing the extracted imports and the content of the resource
+     *                         without
+     *                         import statements.
+     */
+    public static ExtractImportResult extractImports(String contentResource) {
+        List<String> imports = new ArrayList<>();
+        Matcher m = IMPORT_PATTERN.matcher(contentResource);
+        int beginIndex = 0;
+        while (m.find()) {
+            imports.add(m.group());
+            beginIndex = m.end();
+        }
+        if (beginIndex > 0) {
+            contentResource = contentResource.substring(beginIndex);
+        }
+        return new ExtractImportResult(imports, contentResource);
+    }
+
+    /**
+     * {@code ExtractImportResult} represents the result of an imports' extraction.
+     */
+    public static class ExtractImportResult {
+
+        /**
+         * The list of extracted imports.
+         */
+        private final List<String> imports;
+        /**
+         * The content of the resource without import statement.
+         */
+        private final String content;
+
+        public ExtractImportResult(List<String> imports, String content) {
+            this.imports = imports;
+            this.content = content;
+        }
+
+        public List<String> getImports() {
+            return imports;
+        }
+
+        public String getContent() {
+            return content;
+        }
+    }
+}
diff --git a/extensions/groovy-dsl/deployment/pom.xml b/extensions-support/dsl/pom.xml
similarity index 51%
copy from extensions/groovy-dsl/deployment/pom.xml
copy to extensions-support/dsl/pom.xml
index c8b563e0c9..01912d5f76 100644
--- a/extensions/groovy-dsl/deployment/pom.xml
+++ b/extensions-support/dsl/pom.xml
@@ -21,41 +21,17 @@
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>org.apache.camel.quarkus</groupId>
-        <artifactId>camel-quarkus-groovy-dsl-parent</artifactId>
+        <artifactId>camel-quarkus-extensions-support</artifactId>
         <version>2.16.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 
-    <artifactId>camel-quarkus-groovy-dsl-deployment</artifactId>
-    <name>Camel Quarkus :: Groovy DSL :: Deployment</name>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.camel.quarkus</groupId>
-            <artifactId>camel-quarkus-core-deployment</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.camel.quarkus</groupId>
-            <artifactId>camel-quarkus-groovy-dsl</artifactId>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-compiler-plugin</artifactId>
-                <configuration>
-                    <annotationProcessorPaths>
-                        <path>
-                            <groupId>io.quarkus</groupId>
-                            <artifactId>quarkus-extension-processor</artifactId>
-                            <version>${quarkus.version}</version>
-                        </path>
-                    </annotationProcessorPaths>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
+    <artifactId>camel-quarkus-support-dsl-parent</artifactId>
+    <name>Camel Quarkus :: Support :: DSL</name>
+    <packaging>pom</packaging>
 
+    <modules>
+        <module>deployment</module>
+        <module>runtime</module>
+    </modules>
 </project>
diff --git a/extensions/kotlin-dsl/deployment/pom.xml b/extensions-support/dsl/runtime/pom.xml
similarity index 78%
copy from extensions/kotlin-dsl/deployment/pom.xml
copy to extensions-support/dsl/runtime/pom.xml
index 5e6aa3fea8..37c195aee7 100644
--- a/extensions/kotlin-dsl/deployment/pom.xml
+++ b/extensions-support/dsl/runtime/pom.xml
@@ -21,31 +21,32 @@
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>org.apache.camel.quarkus</groupId>
-        <artifactId>camel-quarkus-kotlin-dsl-parent</artifactId>
+        <artifactId>camel-quarkus-support-dsl-parent</artifactId>
         <version>2.16.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 
-    <artifactId>camel-quarkus-kotlin-dsl-deployment</artifactId>
-    <name>Camel Quarkus :: Kotlin DSL :: Deployment</name>
+    <artifactId>camel-quarkus-support-dsl</artifactId>
+    <name>Camel Quarkus :: Support :: DSL :: Runtime</name>
+
+    <properties>
+        <camel.quarkus.jvmSince>2.16.0</camel.quarkus.jvmSince>
+        <camel.quarkus.nativeSince>2.16.0</camel.quarkus.nativeSince>
+    </properties>
 
     <dependencies>
-        <dependency>
-            <groupId>io.quarkus</groupId>
-            <artifactId>quarkus-kotlin-deployment</artifactId>
-        </dependency>
         <dependency>
             <groupId>org.apache.camel.quarkus</groupId>
-            <artifactId>camel-quarkus-core-deployment</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.camel.quarkus</groupId>
-            <artifactId>camel-quarkus-kotlin-dsl</artifactId>
+            <artifactId>camel-quarkus-core</artifactId>
         </dependency>
     </dependencies>
 
     <build>
         <plugins>
+            <plugin>
+                <groupId>io.quarkus</groupId>
+                <artifactId>quarkus-extension-maven-plugin</artifactId>
+            </plugin>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-compiler-plugin</artifactId>
@@ -61,5 +62,4 @@
             </plugin>
         </plugins>
     </build>
-
 </project>
diff --git a/extensions/kotlin-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/kotlin/runtime/KotlinDslRecorder.java b/extensions-support/dsl/runtime/src/main/java/org/apache/camel/quarkus/support/dsl/runtime/DslRecorder.java
similarity index 59%
rename from extensions/kotlin-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/kotlin/runtime/KotlinDslRecorder.java
rename to extensions-support/dsl/runtime/src/main/java/org/apache/camel/quarkus/support/dsl/runtime/DslRecorder.java
index 7a1f3068ff..8f70b337ba 100644
--- a/extensions/kotlin-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/kotlin/runtime/KotlinDslRecorder.java
+++ b/extensions-support/dsl/runtime/src/main/java/org/apache/camel/quarkus/support/dsl/runtime/DslRecorder.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.quarkus.dsl.kotlin.runtime;
+package org.apache.camel.quarkus.support.dsl.runtime;
 
 import java.lang.reflect.Constructor;
 
@@ -26,21 +26,30 @@ import org.apache.camel.builder.endpoint.EndpointRouteBuilder;
 import org.apache.camel.support.ResourceHelper;
 
 @Recorder
-public class KotlinDslRecorder {
+public class DslRecorder {
 
-    public void registerRoutesBuilder(RuntimeValue<CamelContext> camelContext, String className, String location)
+    @SuppressWarnings("unchecked")
+    public void registerRoutesBuilder(RuntimeValue<CamelContext> camelContext, String className, String location,
+            boolean instantiateWithCamelContext)
             throws Exception {
-        Constructor<? extends Configurer> constructor = (Constructor<? extends Configurer>) Class.forName(className)
-                .getDeclaredConstructor(EndpointRouteBuilder.class);
-        camelContext.getValue().addRoutes(
+        Class<?> clazz = Class.forName(className);
+        Class<?>[] constructorParameterTypes = instantiateWithCamelContext
+                ? new Class<?>[] { EndpointRouteBuilder.class, CamelContext.class }
+                : new Class<?>[] { EndpointRouteBuilder.class };
+        Constructor<? extends RoutesBuilderConfigurer> constructor = (Constructor<? extends RoutesBuilderConfigurer>) clazz
+                .getDeclaredConstructor(constructorParameterTypes);
+        CamelContext context = camelContext.getValue();
+        context.addRoutes(
                 new EndpointRouteBuilder() {
 
                     @Override
-                    public void configure() throws Exception {
-                        setCamelContext(camelContext.getValue());
+                    public void configure() {
+                        setCamelContext(context);
                         setResource(ResourceHelper.fromString(location, ""));
                         try {
-                            constructor.newInstance(this).configure();
+                            RoutesBuilderConfigurer configurer = instantiateWithCamelContext
+                                    ? constructor.newInstance(this, context) : constructor.newInstance(this);
+                            configurer.configure();
                         } catch (Exception e) {
                             throw new RuntimeCamelException("Cannot create instance of class: " + className, e);
                         }
diff --git a/extensions/kotlin-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/kotlin/runtime/Configurer.java b/extensions-support/dsl/runtime/src/main/java/org/apache/camel/quarkus/support/dsl/runtime/RoutesBuilderConfigurer.java
similarity index 67%
copy from extensions/kotlin-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/kotlin/runtime/Configurer.java
copy to extensions-support/dsl/runtime/src/main/java/org/apache/camel/quarkus/support/dsl/runtime/RoutesBuilderConfigurer.java
index 3e69e9f086..6ebd25edd2 100644
--- a/extensions/kotlin-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/kotlin/runtime/Configurer.java
+++ b/extensions-support/dsl/runtime/src/main/java/org/apache/camel/quarkus/support/dsl/runtime/RoutesBuilderConfigurer.java
@@ -14,17 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.quarkus.dsl.kotlin.runtime;
+package org.apache.camel.quarkus.support.dsl.runtime;
 
-import org.apache.camel.builder.endpoint.EndpointRouteBuilder;
-import org.apache.camel.dsl.kotlin.KotlinDSL;
-import org.jetbrains.annotations.NotNull;
-
-public abstract class Configurer extends KotlinDSL {
-
-    protected Configurer(@NotNull EndpointRouteBuilder builder) {
-        super(builder);
-    }
+/**
+ * {@code RoutesBuilderConfigurer} allows to configure a {@code RoutesBuilder} to create new routes.
+ */
+public interface RoutesBuilderConfigurer {
 
-    public abstract void configure();
+    void configure();
 }
diff --git a/extensions-support/dsl/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions-support/dsl/runtime/src/main/resources/META-INF/quarkus-extension.yaml
new file mode 100644
index 0000000000..24584344a8
--- /dev/null
+++ b/extensions-support/dsl/runtime/src/main/resources/META-INF/quarkus-extension.yaml
@@ -0,0 +1,27 @@
+#
+# 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.
+#
+
+---
+name: "Camel Quarkus Support DSL"
+description: "Camel Quarkus Support DSL"
+metadata:
+  unlisted: true
+  keywords:
+  - "camel"
+  guide: "https://quarkus.io/guides/camel"
+  categories:
+  - "integration"
diff --git a/extensions-support/pom.xml b/extensions-support/pom.xml
index 360102e181..f73d773030 100644
--- a/extensions-support/pom.xml
+++ b/extensions-support/pom.xml
@@ -43,6 +43,7 @@
         <module>commons-logging</module>
         <module>consul-client</module>
         <module>debezium</module>
+        <module>dsl</module>
         <module>google-cloud</module>
         <module>google-http-client</module>
         <module>httpclient</module>
diff --git a/extensions/groovy-dsl/deployment/pom.xml b/extensions/groovy-dsl/deployment/pom.xml
index c8b563e0c9..81c239e0c8 100644
--- a/extensions/groovy-dsl/deployment/pom.xml
+++ b/extensions/groovy-dsl/deployment/pom.xml
@@ -34,6 +34,10 @@
             <groupId>org.apache.camel.quarkus</groupId>
             <artifactId>camel-quarkus-core-deployment</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-support-dsl-deployment</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.apache.camel.quarkus</groupId>
             <artifactId>camel-quarkus-groovy-dsl</artifactId>
diff --git a/extensions/groovy-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/groovy/deployment/GroovyDslProcessor.java b/extensions/groovy-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/groovy/deployment/GroovyDslProcessor.java
index c97336d80e..739c7221d6 100644
--- a/extensions/groovy-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/groovy/deployment/GroovyDslProcessor.java
+++ b/extensions/groovy-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/groovy/deployment/GroovyDslProcessor.java
@@ -24,14 +24,10 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
 import io.quarkus.deployment.annotations.BuildProducer;
 import io.quarkus.deployment.annotations.BuildStep;
-import io.quarkus.deployment.annotations.ExecutionTime;
-import io.quarkus.deployment.annotations.Record;
 import io.quarkus.deployment.builditem.FeatureBuildItem;
 import io.quarkus.deployment.builditem.GeneratedClassBuildItem;
 import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
@@ -39,14 +35,11 @@ import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem;
 import io.quarkus.deployment.pkg.steps.NativeBuild;
 import io.quarkus.maven.dependency.ResolvedDependency;
 import io.quarkus.paths.PathCollection;
-import io.quarkus.runtime.RuntimeValue;
-import org.apache.camel.CamelContext;
 import org.apache.camel.quarkus.core.deployment.main.CamelMainHelper;
-import org.apache.camel.quarkus.core.deployment.spi.CamelContextBuildItem;
 import org.apache.camel.quarkus.dsl.groovy.runtime.Configurer;
-import org.apache.camel.quarkus.dsl.groovy.runtime.GroovyDslRecorder;
+import org.apache.camel.quarkus.support.dsl.deployment.DslGeneratedClassBuildItem;
+import org.apache.camel.quarkus.support.dsl.deployment.DslSupportProcessor;
 import org.apache.camel.spi.Resource;
-import org.apache.camel.util.FileUtil;
 import org.apache.camel.util.IOHelper;
 import org.codehaus.groovy.control.CompilationUnit;
 import org.codehaus.groovy.control.CompilerConfiguration;
@@ -55,11 +48,13 @@ import org.codehaus.groovy.tools.GroovyClass;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import static org.apache.camel.quarkus.support.dsl.deployment.DslSupportProcessor.determineName;
+import static org.apache.camel.quarkus.support.dsl.deployment.DslSupportProcessor.extractImports;
+
 public class GroovyDslProcessor {
 
     private static final Logger LOG = LoggerFactory.getLogger(GroovyDslProcessor.class);
     private static final String PACKAGE_NAME = "org.apache.camel.quarkus.dsl.groovy.generated";
-    private static final Pattern IMPORT_PATTERN = Pattern.compile("import .*");
     private static final String FILE_FORMAT = "package %s\n" +
             "%s\n" +
             "@groovy.transform.InheritConstructors \n" +
@@ -78,7 +73,7 @@ public class GroovyDslProcessor {
     @BuildStep(onlyIf = NativeBuild.class)
     void compileScriptsAOT(BuildProducer<GeneratedClassBuildItem> generatedClass,
             BuildProducer<ReflectiveClassBuildItem> reflectiveClass,
-            BuildProducer<GroovyGeneratedClassBuildItem> generatedGroovyClass,
+            BuildProducer<DslGeneratedClassBuildItem> generatedGroovyClass,
             CurateOutcomeBuildItem curateOutcomeBuildItem) throws Exception {
         LOG.debug("Loading .groovy resources");
         Map<String, Resource> nameToResource = new HashMap<>();
@@ -115,22 +110,11 @@ public class GroovyDslProcessor {
             if (nameToResource.containsKey(className)) {
                 reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, className));
                 generatedGroovyClass
-                        .produce(new GroovyGeneratedClassBuildItem(className, nameToResource.get(className).getLocation()));
+                        .produce(new DslGeneratedClassBuildItem(className, nameToResource.get(className).getLocation()));
             }
         }
     }
 
-    @BuildStep(onlyIf = NativeBuild.class)
-    @Record(value = ExecutionTime.STATIC_INIT)
-    void registerRoutesBuilder(List<GroovyGeneratedClassBuildItem> classes,
-            CamelContextBuildItem context,
-            GroovyDslRecorder recorder) throws Exception {
-        RuntimeValue<CamelContext> camelContext = context.getCamelContext();
-        for (GroovyGeneratedClassBuildItem clazz : classes) {
-            recorder.registerRoutesBuilder(camelContext, clazz.getName(), clazz.getLocation());
-        }
-    }
-
     // To put it back once the Groovy extensions will be supported (https://github.com/apache/camel-quarkus/issues/4384)
     //    @BuildStep
     //    void registerNativeImageResources(BuildProducer<ServiceProviderBuildItem> serviceProvider) {
@@ -138,20 +122,6 @@ public class GroovyDslProcessor {
     //                .produce(ServiceProviderBuildItem.allProvidersFromClassPath("org.codehaus.groovy.runtime.ExtensionModule"));
     //    }
 
-    private static String determineName(Resource resource) {
-        String str = FileUtil.onlyName(resource.getLocation(), true);
-        StringBuilder sb = new StringBuilder();
-        for (int i = 0, length = str.length(); i < length; i++) {
-            char c = str.charAt(i);
-            if ((i == 0 && Character.isJavaIdentifierStart(c)) || (i > 0 && Character.isJavaIdentifierPart(c))) {
-                sb.append(c);
-            } else {
-                sb.append((int) c);
-            }
-        }
-        return sb.toString();
-    }
-
     /**
      * Convert a Groovy script into a Groovy class to be able to compile it.
      *
@@ -163,16 +133,10 @@ public class GroovyDslProcessor {
         List<String> imports = new ArrayList<>();
         imports.add("import org.apache.camel.*");
         imports.add("import org.apache.camel.spi.*");
-        Matcher m = IMPORT_PATTERN.matcher(contentResource);
-        int beginIndex = 0;
-        while (m.find()) {
-            imports.add(m.group());
-            beginIndex = m.end();
-        }
-        if (beginIndex > 0) {
-            contentResource = contentResource.substring(beginIndex);
-        }
+        DslSupportProcessor.ExtractImportResult extractImportResult = extractImports(contentResource);
+        imports.addAll(extractImportResult.getImports());
         return String.format(
-                FILE_FORMAT, PACKAGE_NAME, String.join("\n", imports), name, Configurer.class.getName(), contentResource);
+                FILE_FORMAT, PACKAGE_NAME, String.join("\n", imports), name, Configurer.class.getName(),
+                extractImportResult.getContent());
     }
 }
diff --git a/extensions/groovy-dsl/runtime/pom.xml b/extensions/groovy-dsl/runtime/pom.xml
index d41a33af8e..ebcd15a650 100644
--- a/extensions/groovy-dsl/runtime/pom.xml
+++ b/extensions/groovy-dsl/runtime/pom.xml
@@ -40,6 +40,10 @@
             <groupId>org.apache.camel.quarkus</groupId>
             <artifactId>camel-quarkus-core</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-support-dsl</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.apache.camel</groupId>
             <artifactId>camel-groovy-dsl</artifactId>
diff --git a/extensions/groovy-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/groovy/runtime/Configurer.java b/extensions/groovy-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/groovy/runtime/Configurer.java
index c892ef1a42..b4c39432e7 100644
--- a/extensions/groovy-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/groovy/runtime/Configurer.java
+++ b/extensions/groovy-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/groovy/runtime/Configurer.java
@@ -18,13 +18,13 @@ package org.apache.camel.quarkus.dsl.groovy.runtime;
 
 import org.apache.camel.builder.endpoint.EndpointRouteBuilder;
 import org.apache.camel.dsl.groovy.common.GroovyDSL;
+import org.apache.camel.quarkus.support.dsl.runtime.RoutesBuilderConfigurer;
 
-public abstract class Configurer extends GroovyDSL {
+public abstract class Configurer extends GroovyDSL implements RoutesBuilderConfigurer {
 
     // The constructor needs to remain public to be accessible from a Groovy Script
     public Configurer(EndpointRouteBuilder builder) {
         super(builder);
     }
 
-    public abstract void configure();
 }
diff --git a/extensions/groovy-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/groovy/runtime/GroovyDslRecorder.java b/extensions/groovy-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/groovy/runtime/GroovyDslRecorder.java
deleted file mode 100644
index 95d9904a41..0000000000
--- a/extensions/groovy-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/groovy/runtime/GroovyDslRecorder.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.quarkus.dsl.groovy.runtime;
-
-import java.lang.reflect.Constructor;
-
-import io.quarkus.runtime.RuntimeValue;
-import io.quarkus.runtime.annotations.Recorder;
-import org.apache.camel.CamelContext;
-import org.apache.camel.RuntimeCamelException;
-import org.apache.camel.builder.endpoint.EndpointRouteBuilder;
-import org.apache.camel.support.ResourceHelper;
-
-@Recorder
-public class GroovyDslRecorder {
-    public void registerRoutesBuilder(RuntimeValue<CamelContext> camelContext, String className, String location)
-            throws Exception {
-        Constructor<? extends Configurer> constructor = (Constructor<? extends Configurer>) Class.forName(className)
-                .getDeclaredConstructor(EndpointRouteBuilder.class);
-        camelContext.getValue().addRoutes(
-                new EndpointRouteBuilder() {
-
-                    @Override
-                    public void configure() throws Exception {
-                        setCamelContext(camelContext.getValue());
-                        setResource(ResourceHelper.fromString(location, ""));
-                        try {
-                            constructor.newInstance(this).configure();
-                        } catch (Exception e) {
-                            throw new RuntimeCamelException("Cannot create instance of class: " + className, e);
-                        }
-                    }
-                });
-    }
-}
diff --git a/extensions/kotlin-dsl/deployment/pom.xml b/extensions/jsh-dsl/deployment/pom.xml
similarity index 77%
copy from extensions/kotlin-dsl/deployment/pom.xml
copy to extensions/jsh-dsl/deployment/pom.xml
index 5e6aa3fea8..2289032e39 100644
--- a/extensions/kotlin-dsl/deployment/pom.xml
+++ b/extensions/jsh-dsl/deployment/pom.xml
@@ -17,30 +17,32 @@
     limitations under the License.
 
 -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>org.apache.camel.quarkus</groupId>
-        <artifactId>camel-quarkus-kotlin-dsl-parent</artifactId>
+        <artifactId>camel-quarkus-jsh-dsl-parent</artifactId>
         <version>2.16.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 
-    <artifactId>camel-quarkus-kotlin-dsl-deployment</artifactId>
-    <name>Camel Quarkus :: Kotlin DSL :: Deployment</name>
+    <artifactId>camel-quarkus-jsh-dsl-deployment</artifactId>
+    <name>Camel Quarkus :: JavaShell DSL :: Deployment</name>
 
     <dependencies>
         <dependency>
-            <groupId>io.quarkus</groupId>
-            <artifactId>quarkus-kotlin-deployment</artifactId>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-core-deployment</artifactId>
         </dependency>
         <dependency>
             <groupId>org.apache.camel.quarkus</groupId>
-            <artifactId>camel-quarkus-core-deployment</artifactId>
+            <artifactId>camel-quarkus-support-dsl-deployment</artifactId>
         </dependency>
         <dependency>
             <groupId>org.apache.camel.quarkus</groupId>
-            <artifactId>camel-quarkus-kotlin-dsl</artifactId>
+            <artifactId>camel-quarkus-jsh-dsl</artifactId>
         </dependency>
     </dependencies>
 
diff --git a/extensions/kotlin-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/kotlin/deployment/KotlinDslProcessor.java b/extensions/jsh-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/jsh/deployment/JshDslProcessor.java
similarity index 53%
copy from extensions/kotlin-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/kotlin/deployment/KotlinDslProcessor.java
copy to extensions/jsh-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/jsh/deployment/JshDslProcessor.java
index 6a9e71d172..d1582eeb19 100644
--- a/extensions/kotlin-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/kotlin/deployment/KotlinDslProcessor.java
+++ b/extensions/jsh-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/jsh/deployment/JshDslProcessor.java
@@ -14,8 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-package org.apache.camel.quarkus.dsl.kotlin.deployment;
+package org.apache.camel.quarkus.dsl.jsh.deployment;
 
 import java.io.File;
 import java.io.IOException;
@@ -30,54 +29,49 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 import io.quarkus.deployment.annotations.BuildProducer;
 import io.quarkus.deployment.annotations.BuildStep;
-import io.quarkus.deployment.annotations.ExecutionTime;
-import io.quarkus.deployment.annotations.Record;
 import io.quarkus.deployment.builditem.FeatureBuildItem;
 import io.quarkus.deployment.builditem.GeneratedClassBuildItem;
 import io.quarkus.deployment.builditem.GeneratedResourceBuildItem;
 import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
 import io.quarkus.deployment.dev.CompilationProvider;
+import io.quarkus.deployment.dev.JavaCompilationProvider;
 import io.quarkus.deployment.pkg.builditem.BuildSystemTargetBuildItem;
 import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem;
 import io.quarkus.deployment.pkg.steps.NativeBuild;
-import io.quarkus.kotlin.deployment.KotlinCompilationProvider;
 import io.quarkus.maven.dependency.ResolvedDependency;
 import io.quarkus.paths.PathCollection;
-import io.quarkus.runtime.RuntimeValue;
-import org.apache.camel.CamelContext;
-import org.apache.camel.dsl.kotlin.KotlinConstantsKt;
 import org.apache.camel.quarkus.core.deployment.main.CamelMainHelper;
-import org.apache.camel.quarkus.core.deployment.spi.CamelContextBuildItem;
-import org.apache.camel.quarkus.dsl.kotlin.runtime.Configurer;
-import org.apache.camel.quarkus.dsl.kotlin.runtime.KotlinDslRecorder;
+import org.apache.camel.quarkus.dsl.jsh.runtime.Configurer;
+import org.apache.camel.quarkus.support.dsl.deployment.DslGeneratedClassBuildItem;
+import org.apache.camel.quarkus.support.dsl.deployment.DslSupportProcessor;
 import org.apache.camel.spi.Resource;
-import org.apache.camel.util.FileUtil;
 import org.apache.camel.util.IOHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-class KotlinDslProcessor {
+import static org.apache.camel.quarkus.support.dsl.deployment.DslSupportProcessor.CLASS_EXT;
+import static org.apache.camel.quarkus.support.dsl.deployment.DslSupportProcessor.determineName;
+import static org.apache.camel.quarkus.support.dsl.deployment.DslSupportProcessor.extractImports;
 
-    private static final Logger LOG = LoggerFactory.getLogger(KotlinDslProcessor.class);
-    private static final String PACKAGE_NAME = "org.apache.camel.quarkus.dsl.kotlin.generated";
-    private static final Pattern IMPORT_PATTERN = Pattern.compile("import .*");
-    private static final String FILE_FORMAT = "package %s\n" +
+class JshDslProcessor {
+    private static final Logger LOG = LoggerFactory.getLogger(JshDslProcessor.class);
+    private static final String PACKAGE_NAME = "org.apache.camel.quarkus.dsl.jsh.generated";
+    private static final String FILE_FORMAT = "package %s;\n" +
             "%s\n" +
-            "class %s(builder: org.apache.camel.builder.endpoint.EndpointRouteBuilder) :\n" +
-            "  %s(builder) { \n" +
-            "  override fun configure() { \n" +
+            "public class %s extends %s { \n" +
+            "  public %s(EndpointRouteBuilder builder, CamelContext context) {\n" +
+            "    super(builder, context);\n" +
+            "  }\n" +
+            "  public void configure() { \n" +
             "    %s\n" +
             "  }\n" +
             "}";
-    private static final String FEATURE = "camel-kotlin-dsl";
-    public static final String CLASS_EXT = ".class";
+    private static final String FEATURE = "camel-jsh-dsl";
 
     @BuildStep
     FeatureBuildItem feature() {
@@ -88,13 +82,13 @@ class KotlinDslProcessor {
     void compileScriptsAOT(BuildProducer<GeneratedClassBuildItem> generatedClass,
             BuildProducer<GeneratedResourceBuildItem> generatedResource,
             BuildProducer<ReflectiveClassBuildItem> reflectiveClass,
-            BuildProducer<KotlinGeneratedClassBuildItem> generatedKotlinClass,
+            BuildProducer<DslGeneratedClassBuildItem> generatedJavaClass,
             BuildSystemTargetBuildItem buildSystemTargetBuildItem,
             CurateOutcomeBuildItem curateOutcomeBuildItem) throws Exception {
-        LOG.debug("Loading .kts resources");
+        LOG.debug("Loading .jsh resources");
         final Path projectDir = Paths.get(".").toAbsolutePath().normalize();
         Path outputDirectory = buildSystemTargetBuildItem.getOutputDirectory();
-        final Path generatedSourceDir = outputDirectory.resolve("kotlin-dsl/generated-sources");
+        final Path generatedSourceDir = outputDirectory.resolve("jsh-dsl/generated-sources");
         Files.createDirectories(generatedSourceDir);
         final Path generatedSourceHomeDir = generatedSourceDir.resolve(PACKAGE_NAME.replace('.', File.separatorChar));
         Files.createDirectories(generatedSourceHomeDir);
@@ -102,14 +96,14 @@ class KotlinDslProcessor {
         Set<File> filesToCompile = new HashSet<>();
         CamelMainHelper.forEachMatchingResource(
                 resource -> {
-                    if (!resource.getLocation().endsWith(".kts")) {
+                    if (!resource.getLocation().endsWith(".jsh")) {
                         return;
                     }
                     String name = determineName(resource);
                     try (InputStream is = resource.getInputStream()) {
-                        String content = toKotlinClass(name, IOHelper.loadText(is));
-                        LOG.debug("Generated Kotlin source content:\n {}", content);
-                        final Path sourceFile = generatedSourceHomeDir.resolve(String.format("%s.kt", name));
+                        String content = toJavaClass(name, IOHelper.loadText(is));
+                        LOG.debug("Generated Java source content:\n {}", content);
+                        final Path sourceFile = generatedSourceHomeDir.resolve(String.format("%s.java", name));
                         Files.write(sourceFile, content.getBytes(StandardCharsets.UTF_8));
                         filesToCompile.add(sourceFile.toFile());
                         nameToResource.put(String.format("%s.%s", PACKAGE_NAME, name), resource);
@@ -121,7 +115,7 @@ class KotlinDslProcessor {
         if (filesToCompile.isEmpty()) {
             return;
         }
-        final Path classesDir = outputDirectory.resolve("kotlin-dsl/generated-classes");
+        final Path classesDir = outputDirectory.resolve("jsh-dsl/generated-classes");
         Files.createDirectories(classesDir);
         CompilationProvider.Context context = new CompilationProvider.Context(
                 FEATURE,
@@ -137,12 +131,12 @@ class KotlinDslProcessor {
                 classesDir.toFile(),
                 StandardCharsets.UTF_8.name(),
                 Map.of(),
-                KotlinConstantsKt.JVM_TARGET,
-                KotlinConstantsKt.JVM_TARGET,
-                KotlinConstantsKt.JVM_TARGET,
+                null,
+                null,
+                null,
                 List.of(),
                 List.of());
-        try (KotlinCompilationProvider compiler = new KotlinCompilationProvider()) {
+        try (JavaCompilationProvider compiler = new JavaCompilationProvider()) {
             compiler.compile(filesToCompile, context);
         }
 
@@ -150,23 +144,16 @@ class KotlinDslProcessor {
             classFiles
                     .filter(Files::isRegularFile)
                     .forEach(p -> {
-                        String fileName = p.getFileName().toString();
                         String relativePath = classesDir.relativize(p).toString();
+                        String className = relativePath.replace(File.separatorChar, '.').substring(0,
+                                relativePath.length() - CLASS_EXT.length());
                         try {
-                            if (fileName.endsWith(CLASS_EXT)) {
-                                String className = relativePath.replace(File.separatorChar, '.').substring(0,
-                                        relativePath.length() - CLASS_EXT.length());
-                                generatedClass.produce(new GeneratedClassBuildItem(true, className, Files.readAllBytes(p)));
-                                if (nameToResource.containsKey(className)) {
-                                    reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, className));
-                                    generatedKotlinClass
-                                            .produce(new KotlinGeneratedClassBuildItem(className,
-                                                    nameToResource.get(className).getLocation()));
-                                }
-                            } else {
-                                generatedResource.produce(new GeneratedResourceBuildItem(
-                                        relativePath.replace(File.separatorChar, '/'),
-                                        Files.readAllBytes(p)));
+                            generatedClass.produce(new GeneratedClassBuildItem(true, className, Files.readAllBytes(p)));
+                            if (nameToResource.containsKey(className)) {
+                                reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, className));
+                                generatedJavaClass
+                                        .produce(new DslGeneratedClassBuildItem(className,
+                                                nameToResource.get(className).getLocation(), true));
                             }
                         } catch (IOException e) {
                             throw new RuntimeException("Could not read " + p);
@@ -175,53 +162,22 @@ class KotlinDslProcessor {
         }
     }
 
-    @BuildStep(onlyIf = NativeBuild.class)
-    @Record(value = ExecutionTime.STATIC_INIT)
-    void registerRoutesBuilder(List<KotlinGeneratedClassBuildItem> classes,
-            CamelContextBuildItem context,
-            KotlinDslRecorder recorder) throws Exception {
-        RuntimeValue<CamelContext> camelContext = context.getCamelContext();
-        for (KotlinGeneratedClassBuildItem clazz : classes) {
-            recorder.registerRoutesBuilder(camelContext, clazz.getName(), clazz.getLocation());
-        }
-    }
-
-    private static String determineName(Resource resource) {
-        String str = FileUtil.onlyName(resource.getLocation(), true);
-        StringBuilder sb = new StringBuilder();
-        for (int i = 0, length = str.length(); i < length; i++) {
-            char c = str.charAt(i);
-            if ((i == 0 && Character.isJavaIdentifierStart(c)) || (i > 0 && Character.isJavaIdentifierPart(c))) {
-                sb.append(c);
-            } else {
-                sb.append((int) c);
-            }
-        }
-        return sb.toString();
-    }
-
     /**
-     * Convert a Kotlin script into a Kotlin class to be able to compile it.
+     * Convert a JShell script into a Java class to be able to compile it.
      *
-     * @param  name            the name of the Kotlin class
-     * @param  contentResource the content of the Kotlin script
-     * @return                 the content of the corresponding Kotlin class.
+     * @param  name            the name of the Java class
+     * @param  contentResource the content of the JShell script
+     * @return                 the content of the corresponding Java class.
      */
-    private static String toKotlinClass(String name, String contentResource) {
+    private static String toJavaClass(String name, String contentResource) {
         List<String> imports = new ArrayList<>();
-        imports.add("import org.apache.camel.*");
-        imports.add("import org.apache.camel.spi.*");
-        Matcher m = IMPORT_PATTERN.matcher(contentResource);
-        int beginIndex = 0;
-        while (m.find()) {
-            imports.add(m.group());
-            beginIndex = m.end();
-        }
-        if (beginIndex > 0) {
-            contentResource = contentResource.substring(beginIndex);
-        }
+        imports.add("import org.apache.camel.*;");
+        imports.add("import org.apache.camel.spi.*;");
+        imports.add("import org.apache.camel.builder.endpoint.EndpointRouteBuilder;");
+        DslSupportProcessor.ExtractImportResult extractImportResult = extractImports(contentResource);
+        imports.addAll(extractImportResult.getImports());
         return String.format(
                 FILE_FORMAT, PACKAGE_NAME, String.join("\n", imports), name,
-                Configurer.class.getName(), contentResource);
+                Configurer.class.getName(), name, extractImportResult.getContent());
     }
 }
diff --git a/extensions/jsh-dsl/pom.xml b/extensions/jsh-dsl/pom.xml
new file mode 100644
index 0000000000..15161ab7d2
--- /dev/null
+++ b/extensions/jsh-dsl/pom.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.camel.quarkus</groupId>
+        <artifactId>camel-quarkus-extensions</artifactId>
+        <version>2.16.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>camel-quarkus-jsh-dsl-parent</artifactId>
+    <name>Camel Quarkus :: JavaShell DSL</name>
+    <packaging>pom</packaging>
+
+    <modules>
+        <module>deployment</module>
+        <module>runtime</module>
+    </modules>
+</project>
diff --git a/extensions/kotlin-dsl/runtime/pom.xml b/extensions/jsh-dsl/runtime/pom.xml
similarity index 82%
copy from extensions/kotlin-dsl/runtime/pom.xml
copy to extensions/jsh-dsl/runtime/pom.xml
index fa381be603..b9dc2a0a9b 100644
--- a/extensions/kotlin-dsl/runtime/pom.xml
+++ b/extensions/jsh-dsl/runtime/pom.xml
@@ -17,36 +17,38 @@
     limitations under the License.
 
 -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>org.apache.camel.quarkus</groupId>
-        <artifactId>camel-quarkus-kotlin-dsl-parent</artifactId>
+        <artifactId>camel-quarkus-jsh-dsl-parent</artifactId>
         <version>2.16.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 
-    <artifactId>camel-quarkus-kotlin-dsl</artifactId>
-    <name>Camel Quarkus :: Kotlin DSL :: Runtime</name>
-    <description>Support for parsing Kotlin route definitions at runtime</description>
+    <artifactId>camel-quarkus-jsh-dsl</artifactId>
+    <name>Camel Quarkus :: JavaShell DSL :: Runtime</name>
+    <description>Camel DSL with JavaShell</description>
 
     <properties>
-        <camel.quarkus.jvmSince>1.8.0</camel.quarkus.jvmSince>
+        <camel.quarkus.jvmSince>2.16.0</camel.quarkus.jvmSince>
         <camel.quarkus.nativeSince>2.16.0</camel.quarkus.nativeSince>
     </properties>
 
     <dependencies>
         <dependency>
-            <groupId>io.quarkus</groupId>
-            <artifactId>quarkus-kotlin</artifactId>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-core</artifactId>
         </dependency>
         <dependency>
             <groupId>org.apache.camel.quarkus</groupId>
-            <artifactId>camel-quarkus-core</artifactId>
+            <artifactId>camel-quarkus-support-dsl</artifactId>
         </dependency>
         <dependency>
             <groupId>org.apache.camel</groupId>
-            <artifactId>camel-kotlin-dsl</artifactId>
+            <artifactId>camel-jsh-dsl</artifactId>
         </dependency>
     </dependencies>
 
@@ -72,6 +74,7 @@
         </plugins>
     </build>
 
+
     <profiles>
         <profile>
             <id>full</id>
diff --git a/extensions/groovy-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/groovy/runtime/Configurer.java b/extensions/jsh-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/jsh/runtime/Configurer.java
similarity index 59%
copy from extensions/groovy-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/groovy/runtime/Configurer.java
copy to extensions/jsh-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/jsh/runtime/Configurer.java
index c892ef1a42..6084efe095 100644
--- a/extensions/groovy-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/groovy/runtime/Configurer.java
+++ b/extensions/jsh-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/jsh/runtime/Configurer.java
@@ -14,17 +14,22 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.quarkus.dsl.groovy.runtime;
+package org.apache.camel.quarkus.dsl.jsh.runtime;
 
+import org.apache.camel.CamelContext;
 import org.apache.camel.builder.endpoint.EndpointRouteBuilder;
-import org.apache.camel.dsl.groovy.common.GroovyDSL;
+import org.apache.camel.quarkus.support.dsl.runtime.RoutesBuilderConfigurer;
+import org.apache.camel.spi.Registry;
 
-public abstract class Configurer extends GroovyDSL {
+public abstract class Configurer implements RoutesBuilderConfigurer {
 
-    // The constructor needs to remain public to be accessible from a Groovy Script
-    public Configurer(EndpointRouteBuilder builder) {
-        super(builder);
-    }
+    protected final EndpointRouteBuilder builder;
+    protected final CamelContext context;
+    protected final Registry registry;
 
-    public abstract void configure();
+    protected Configurer(EndpointRouteBuilder builder, CamelContext context) {
+        this.builder = builder;
+        this.context = context;
+        this.registry = context.getRegistry();
+    }
 }
diff --git a/extensions/kotlin-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/kotlin/deployment/KotlinGeneratedClassBuildItem.java b/extensions/jsh-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/jsh/runtime/graal/SubstituteJshRoutesBuilderLoader.java
similarity index 61%
rename from extensions/kotlin-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/kotlin/deployment/KotlinGeneratedClassBuildItem.java
rename to extensions/jsh-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/jsh/runtime/graal/SubstituteJshRoutesBuilderLoader.java
index a9240ba6ef..3e86c68075 100644
--- a/extensions/kotlin-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/kotlin/deployment/KotlinGeneratedClassBuildItem.java
+++ b/extensions/jsh-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/jsh/runtime/graal/SubstituteJshRoutesBuilderLoader.java
@@ -14,25 +14,20 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.quarkus.dsl.kotlin.deployment;
+package org.apache.camel.quarkus.dsl.jsh.runtime.graal;
 
-import io.quarkus.builder.item.MultiBuildItem;
+import com.oracle.svm.core.annotate.Substitute;
+import com.oracle.svm.core.annotate.TargetClass;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.dsl.jsh.JshRoutesBuilderLoader;
+import org.apache.camel.spi.Resource;
 
-public final class KotlinGeneratedClassBuildItem extends MultiBuildItem {
+@TargetClass(JshRoutesBuilderLoader.class)
+final class SubstituteJshRoutesBuilderLoader {
 
-    final String name;
-    final String location;
-
-    public KotlinGeneratedClassBuildItem(String name, String location) {
-        this.name = name;
-        this.location = location;
-    }
-
-    public String getName() {
-        return this.name;
-    }
-
-    public String getLocation() {
-        return location;
+    @Substitute
+    public RoutesBuilder loadRoutesBuilder(Resource resource) {
+        // Do nothing
+        return null;
     }
 }
diff --git a/extensions/jsh-dsl/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions/jsh-dsl/runtime/src/main/resources/META-INF/quarkus-extension.yaml
new file mode 100644
index 0000000000..ff66d83cbe
--- /dev/null
+++ b/extensions/jsh-dsl/runtime/src/main/resources/META-INF/quarkus-extension.yaml
@@ -0,0 +1,31 @@
+#
+# 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.
+#
+
+# This is a generated file. Do not edit directly!
+# To re-generate, run the following command from the top level directory:
+#
+#   mvn -N cq:update-quarkus-metadata
+#
+---
+name: "Camel JavaShell DSL"
+description: "Camel DSL with JavaShell"
+metadata:
+  guide: "https://camel.apache.org/camel-quarkus/latest/reference/extensions/jsh-dsl.html"
+  categories:
+  - "integration"
+  status:
+  - "stable"
diff --git a/extensions/kotlin-dsl/deployment/pom.xml b/extensions/kotlin-dsl/deployment/pom.xml
index 5e6aa3fea8..e182ec756e 100644
--- a/extensions/kotlin-dsl/deployment/pom.xml
+++ b/extensions/kotlin-dsl/deployment/pom.xml
@@ -38,6 +38,10 @@
             <groupId>org.apache.camel.quarkus</groupId>
             <artifactId>camel-quarkus-core-deployment</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-support-dsl-deployment</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.apache.camel.quarkus</groupId>
             <artifactId>camel-quarkus-kotlin-dsl</artifactId>
diff --git a/extensions/kotlin-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/kotlin/deployment/KotlinDslProcessor.java b/extensions/kotlin-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/kotlin/deployment/KotlinDslProcessor.java
index 6a9e71d172..80a874e1f0 100644
--- a/extensions/kotlin-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/kotlin/deployment/KotlinDslProcessor.java
+++ b/extensions/kotlin-dsl/deployment/src/main/java/org/apache/camel/quarkus/dsl/kotlin/deployment/KotlinDslProcessor.java
@@ -30,15 +30,11 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 import io.quarkus.deployment.annotations.BuildProducer;
 import io.quarkus.deployment.annotations.BuildStep;
-import io.quarkus.deployment.annotations.ExecutionTime;
-import io.quarkus.deployment.annotations.Record;
 import io.quarkus.deployment.builditem.FeatureBuildItem;
 import io.quarkus.deployment.builditem.GeneratedClassBuildItem;
 import io.quarkus.deployment.builditem.GeneratedResourceBuildItem;
@@ -50,24 +46,24 @@ import io.quarkus.deployment.pkg.steps.NativeBuild;
 import io.quarkus.kotlin.deployment.KotlinCompilationProvider;
 import io.quarkus.maven.dependency.ResolvedDependency;
 import io.quarkus.paths.PathCollection;
-import io.quarkus.runtime.RuntimeValue;
-import org.apache.camel.CamelContext;
 import org.apache.camel.dsl.kotlin.KotlinConstantsKt;
 import org.apache.camel.quarkus.core.deployment.main.CamelMainHelper;
-import org.apache.camel.quarkus.core.deployment.spi.CamelContextBuildItem;
 import org.apache.camel.quarkus.dsl.kotlin.runtime.Configurer;
-import org.apache.camel.quarkus.dsl.kotlin.runtime.KotlinDslRecorder;
+import org.apache.camel.quarkus.support.dsl.deployment.DslGeneratedClassBuildItem;
+import org.apache.camel.quarkus.support.dsl.deployment.DslSupportProcessor;
 import org.apache.camel.spi.Resource;
-import org.apache.camel.util.FileUtil;
 import org.apache.camel.util.IOHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import static org.apache.camel.quarkus.support.dsl.deployment.DslSupportProcessor.CLASS_EXT;
+import static org.apache.camel.quarkus.support.dsl.deployment.DslSupportProcessor.determineName;
+import static org.apache.camel.quarkus.support.dsl.deployment.DslSupportProcessor.extractImports;
+
 class KotlinDslProcessor {
 
     private static final Logger LOG = LoggerFactory.getLogger(KotlinDslProcessor.class);
     private static final String PACKAGE_NAME = "org.apache.camel.quarkus.dsl.kotlin.generated";
-    private static final Pattern IMPORT_PATTERN = Pattern.compile("import .*");
     private static final String FILE_FORMAT = "package %s\n" +
             "%s\n" +
             "class %s(builder: org.apache.camel.builder.endpoint.EndpointRouteBuilder) :\n" +
@@ -77,7 +73,6 @@ class KotlinDslProcessor {
             "  }\n" +
             "}";
     private static final String FEATURE = "camel-kotlin-dsl";
-    public static final String CLASS_EXT = ".class";
 
     @BuildStep
     FeatureBuildItem feature() {
@@ -88,7 +83,7 @@ class KotlinDslProcessor {
     void compileScriptsAOT(BuildProducer<GeneratedClassBuildItem> generatedClass,
             BuildProducer<GeneratedResourceBuildItem> generatedResource,
             BuildProducer<ReflectiveClassBuildItem> reflectiveClass,
-            BuildProducer<KotlinGeneratedClassBuildItem> generatedKotlinClass,
+            BuildProducer<DslGeneratedClassBuildItem> generatedKotlinClass,
             BuildSystemTargetBuildItem buildSystemTargetBuildItem,
             CurateOutcomeBuildItem curateOutcomeBuildItem) throws Exception {
         LOG.debug("Loading .kts resources");
@@ -160,7 +155,7 @@ class KotlinDslProcessor {
                                 if (nameToResource.containsKey(className)) {
                                     reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, className));
                                     generatedKotlinClass
-                                            .produce(new KotlinGeneratedClassBuildItem(className,
+                                            .produce(new DslGeneratedClassBuildItem(className,
                                                     nameToResource.get(className).getLocation()));
                                 }
                             } else {
@@ -175,31 +170,6 @@ class KotlinDslProcessor {
         }
     }
 
-    @BuildStep(onlyIf = NativeBuild.class)
-    @Record(value = ExecutionTime.STATIC_INIT)
-    void registerRoutesBuilder(List<KotlinGeneratedClassBuildItem> classes,
-            CamelContextBuildItem context,
-            KotlinDslRecorder recorder) throws Exception {
-        RuntimeValue<CamelContext> camelContext = context.getCamelContext();
-        for (KotlinGeneratedClassBuildItem clazz : classes) {
-            recorder.registerRoutesBuilder(camelContext, clazz.getName(), clazz.getLocation());
-        }
-    }
-
-    private static String determineName(Resource resource) {
-        String str = FileUtil.onlyName(resource.getLocation(), true);
-        StringBuilder sb = new StringBuilder();
-        for (int i = 0, length = str.length(); i < length; i++) {
-            char c = str.charAt(i);
-            if ((i == 0 && Character.isJavaIdentifierStart(c)) || (i > 0 && Character.isJavaIdentifierPart(c))) {
-                sb.append(c);
-            } else {
-                sb.append((int) c);
-            }
-        }
-        return sb.toString();
-    }
-
     /**
      * Convert a Kotlin script into a Kotlin class to be able to compile it.
      *
@@ -211,17 +181,10 @@ class KotlinDslProcessor {
         List<String> imports = new ArrayList<>();
         imports.add("import org.apache.camel.*");
         imports.add("import org.apache.camel.spi.*");
-        Matcher m = IMPORT_PATTERN.matcher(contentResource);
-        int beginIndex = 0;
-        while (m.find()) {
-            imports.add(m.group());
-            beginIndex = m.end();
-        }
-        if (beginIndex > 0) {
-            contentResource = contentResource.substring(beginIndex);
-        }
+        DslSupportProcessor.ExtractImportResult extractImportResult = extractImports(contentResource);
+        imports.addAll(extractImportResult.getImports());
         return String.format(
                 FILE_FORMAT, PACKAGE_NAME, String.join("\n", imports), name,
-                Configurer.class.getName(), contentResource);
+                Configurer.class.getName(), extractImportResult.getContent());
     }
 }
diff --git a/extensions/kotlin-dsl/runtime/pom.xml b/extensions/kotlin-dsl/runtime/pom.xml
index fa381be603..6c6b01cfbe 100644
--- a/extensions/kotlin-dsl/runtime/pom.xml
+++ b/extensions/kotlin-dsl/runtime/pom.xml
@@ -44,6 +44,10 @@
             <groupId>org.apache.camel.quarkus</groupId>
             <artifactId>camel-quarkus-core</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-support-dsl</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.apache.camel</groupId>
             <artifactId>camel-kotlin-dsl</artifactId>
diff --git a/extensions/kotlin-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/kotlin/runtime/Configurer.java b/extensions/kotlin-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/kotlin/runtime/Configurer.java
index 3e69e9f086..49dbb85156 100644
--- a/extensions/kotlin-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/kotlin/runtime/Configurer.java
+++ b/extensions/kotlin-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/kotlin/runtime/Configurer.java
@@ -18,13 +18,13 @@ package org.apache.camel.quarkus.dsl.kotlin.runtime;
 
 import org.apache.camel.builder.endpoint.EndpointRouteBuilder;
 import org.apache.camel.dsl.kotlin.KotlinDSL;
+import org.apache.camel.quarkus.support.dsl.runtime.RoutesBuilderConfigurer;
 import org.jetbrains.annotations.NotNull;
 
-public abstract class Configurer extends KotlinDSL {
+public abstract class Configurer extends KotlinDSL implements RoutesBuilderConfigurer {
 
     protected Configurer(@NotNull EndpointRouteBuilder builder) {
         super(builder);
     }
 
-    public abstract void configure();
 }
diff --git a/extensions/pom.xml b/extensions/pom.xml
index bf56945982..8fd63b6774 100644
--- a/extensions/pom.xml
+++ b/extensions/pom.xml
@@ -144,6 +144,7 @@
         <module>jq</module>
         <module>js-dsl</module>
         <module>jsch</module>
+        <module>jsh-dsl</module>
         <module>jslt</module>
         <module>json-validator</module>
         <module>jsonata</module>
diff --git a/integration-tests/jsh-dsl/pom.xml b/integration-tests/jsh-dsl/pom.xml
new file mode 100644
index 0000000000..3ca9c6ff20
--- /dev/null
+++ b/integration-tests/jsh-dsl/pom.xml
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.camel.quarkus</groupId>
+        <artifactId>camel-quarkus-build-parent-it</artifactId>
+        <version>2.16.0-SNAPSHOT</version>
+        <relativePath>../../poms/build-parent-it/pom.xml</relativePath>
+    </parent>
+
+    <artifactId>camel-quarkus-integration-test-jsh-dsl</artifactId>
+    <name>Camel Quarkus :: Integration Tests :: JavaShell DSL</name>
+    <description>Integration tests for Camel Quarkus JavaShell DSL extension</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-jsh-dsl</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-resteasy</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel.quarkus</groupId>
+            <artifactId>camel-quarkus-direct</artifactId>
+        </dependency>
+
+        <!-- test dependencies -->
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-junit5</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>io.rest-assured</groupId>
+            <artifactId>rest-assured</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <profiles>
+        <profile>
+            <id>native</id>
+            <activation>
+                <property>
+                    <name>native</name>
+                </property>
+            </activation>
+            <properties>
+                <quarkus.package.type>native</quarkus.package.type>
+            </properties>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-failsafe-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <goals>
+                                    <goal>integration-test</goal>
+                                    <goal>verify</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>virtualDependencies</id>
+            <activation>
+                <property>
+                    <name>!noVirtualDependencies</name>
+                </property>
+            </activation>
+            <dependencies>
+                <!-- The following dependencies guarantee that this module is built after them. You can update them by running `mvn process-resources -Pformat -N` from the source tree root directory -->
+                <dependency>
+                    <groupId>org.apache.camel.quarkus</groupId>
+                    <artifactId>camel-quarkus-direct-deployment</artifactId>
+                    <version>${project.version}</version>
+                    <type>pom</type>
+                    <scope>test</scope>
+                    <exclusions>
+                        <exclusion>
+                            <groupId>*</groupId>
+                            <artifactId>*</artifactId>
+                        </exclusion>
+                    </exclusions>
+                </dependency>
+                <dependency>
+                    <groupId>org.apache.camel.quarkus</groupId>
+                    <artifactId>camel-quarkus-jsh-dsl-deployment</artifactId>
+                    <version>${project.version}</version>
+                    <type>pom</type>
+                    <scope>test</scope>
+                    <exclusions>
+                        <exclusion>
+                            <groupId>*</groupId>
+                            <artifactId>*</artifactId>
+                        </exclusion>
+                    </exclusions>
+                </dependency>
+            </dependencies>
+        </profile>
+    </profiles>
+
+</project>
diff --git a/integration-tests/jsh-dsl/src/main/java/org/apache/camel/quarkus/dsl/jsh/JshDslResource.java b/integration-tests/jsh-dsl/src/main/java/org/apache/camel/quarkus/dsl/jsh/JshDslResource.java
new file mode 100644
index 0000000000..57a9c42d13
--- /dev/null
+++ b/integration-tests/jsh-dsl/src/main/java/org/apache/camel/quarkus/dsl/jsh/JshDslResource.java
@@ -0,0 +1,82 @@
+/*
+ * 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.quarkus.dsl.jsh;
+
+import java.util.stream.Collectors;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import org.apache.camel.ExtendedCamelContext;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.Route;
+import org.apache.camel.dsl.jsh.JshRoutesBuilderLoader;
+import org.apache.camel.quarkus.main.CamelMain;
+import org.apache.camel.spi.RoutesBuilderLoader;
+
+@Path("/jsh-dsl")
+@ApplicationScoped
+public class JshDslResource {
+    @Inject
+    CamelMain main;
+
+    @Inject
+    ProducerTemplate producerTemplate;
+
+    @Path("/main/jshRoutesBuilderLoader")
+    @GET
+    @Produces(MediaType.TEXT_PLAIN)
+    public String jshRoutesBuilder() {
+        final ExtendedCamelContext camelContext = main.getCamelContext().adapt(ExtendedCamelContext.class);
+        return camelContext.getBootstrapFactoryFinder(RoutesBuilderLoader.FACTORY_PATH)
+                .findClass(JshRoutesBuilderLoader.EXTENSION).get().getName();
+    }
+
+    @Path("/main/routeBuilders")
+    @GET
+    @Produces(MediaType.TEXT_PLAIN)
+    public String routeBuilders() {
+        return main.configure().getRoutesBuilders().stream()
+                .map(rb -> rb.getClass().getSimpleName())
+                .sorted()
+                .collect(Collectors.joining(","));
+    }
+
+    @Path("/main/routes")
+    @GET
+    @Produces(MediaType.TEXT_PLAIN)
+    public String routes() {
+        return main.getCamelContext().getRoutes().stream()
+                .map(Route::getId)
+                .sorted()
+                .collect(Collectors.joining(","));
+    }
+
+    @POST
+    @Path("/hello")
+    @Consumes(MediaType.TEXT_PLAIN)
+    @Produces(MediaType.TEXT_PLAIN)
+    public String hello(String message) {
+        return producerTemplate.requestBody("direct:jshHello", message, String.class);
+    }
+}
diff --git a/integration-tests/jsh-dsl/src/main/resources/application.properties b/integration-tests/jsh-dsl/src/main/resources/application.properties
new file mode 100644
index 0000000000..d102a9146d
--- /dev/null
+++ b/integration-tests/jsh-dsl/src/main/resources/application.properties
@@ -0,0 +1,21 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+#
+# Main
+#
+camel.main.routes-include-pattern = classpath:routes/*.jsh
diff --git a/extensions/kotlin-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/kotlin/runtime/Configurer.java b/integration-tests/jsh-dsl/src/main/resources/routes/MyRoute.jsh
similarity index 67%
copy from extensions/kotlin-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/kotlin/runtime/Configurer.java
copy to integration-tests/jsh-dsl/src/main/resources/routes/MyRoute.jsh
index 3e69e9f086..89a3414d1e 100644
--- a/extensions/kotlin-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/kotlin/runtime/Configurer.java
+++ b/integration-tests/jsh-dsl/src/main/resources/routes/MyRoute.jsh
@@ -14,17 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.quarkus.dsl.kotlin.runtime;
 
-import org.apache.camel.builder.endpoint.EndpointRouteBuilder;
-import org.apache.camel.dsl.kotlin.KotlinDSL;
-import org.jetbrains.annotations.NotNull;
-
-public abstract class Configurer extends KotlinDSL {
-
-    protected Configurer(@NotNull EndpointRouteBuilder builder) {
-        super(builder);
-    }
-
-    public abstract void configure();
-}
+builder.from("direct:jshHello")
+    .id("my-jsh-route")
+    .setBody(exchange -> "Hello " + exchange.getMessage().getBody()  + " from JShell!");
diff --git a/extensions/kotlin-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/kotlin/runtime/Configurer.java b/integration-tests/jsh-dsl/src/test/java/org/apache/camel/quarkus/dsl/jsh/JshDslIT.java
similarity index 67%
copy from extensions/kotlin-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/kotlin/runtime/Configurer.java
copy to integration-tests/jsh-dsl/src/test/java/org/apache/camel/quarkus/dsl/jsh/JshDslIT.java
index 3e69e9f086..347cc48db6 100644
--- a/extensions/kotlin-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/kotlin/runtime/Configurer.java
+++ b/integration-tests/jsh-dsl/src/test/java/org/apache/camel/quarkus/dsl/jsh/JshDslIT.java
@@ -14,17 +14,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.quarkus.dsl.kotlin.runtime;
+package org.apache.camel.quarkus.dsl.jsh;
 
-import org.apache.camel.builder.endpoint.EndpointRouteBuilder;
-import org.apache.camel.dsl.kotlin.KotlinDSL;
-import org.jetbrains.annotations.NotNull;
+import io.quarkus.test.junit.QuarkusIntegrationTest;
 
-public abstract class Configurer extends KotlinDSL {
+@QuarkusIntegrationTest
+class JshDslIT extends JshDslTest {
 
-    protected Configurer(@NotNull EndpointRouteBuilder builder) {
-        super(builder);
-    }
-
-    public abstract void configure();
 }
diff --git a/integration-tests/jsh-dsl/src/test/java/org/apache/camel/quarkus/dsl/jsh/JshDslTest.java b/integration-tests/jsh-dsl/src/test/java/org/apache/camel/quarkus/dsl/jsh/JshDslTest.java
new file mode 100644
index 0000000000..62a3c27b91
--- /dev/null
+++ b/integration-tests/jsh-dsl/src/test/java/org/apache/camel/quarkus/dsl/jsh/JshDslTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.quarkus.dsl.jsh;
+
+import io.quarkus.test.junit.QuarkusTest;
+import io.restassured.RestAssured;
+import org.apache.camel.dsl.jsh.JshRoutesBuilderLoader;
+import org.hamcrest.CoreMatchers;
+import org.junit.jupiter.api.Test;
+
+@QuarkusTest
+class JshDslTest {
+
+    @Test
+    void jshHello() {
+        RestAssured.given()
+                .body("Brad Smith")
+                .post("/jsh-dsl/hello")
+                .then()
+                .statusCode(200)
+                .body(CoreMatchers.is("Hello Brad Smith from JShell!"));
+    }
+
+    @Test
+    void testMainInstanceWithJavaRoutes() {
+        RestAssured.given()
+                .get("/jsh-dsl/main/jshRoutesBuilderLoader")
+                .then()
+                .statusCode(200)
+                .body(CoreMatchers.is(JshRoutesBuilderLoader.class.getName()));
+
+        RestAssured.given()
+                .get("/jsh-dsl/main/routeBuilders")
+                .then()
+                .statusCode(200)
+                .body(CoreMatchers.is(""));
+
+        RestAssured.given()
+                .get("/jsh-dsl/main/routes")
+                .then()
+                .statusCode(200)
+                .body(CoreMatchers.is("my-jsh-route"));
+    }
+
+}
diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml
index 043063a5b4..864ac6c0d1 100644
--- a/integration-tests/pom.xml
+++ b/integration-tests/pom.xml
@@ -127,6 +127,7 @@
         <module>jq</module>
         <module>js-dsl</module>
         <module>jsch</module>
+        <module>jsh-dsl</module>
         <module>jslt</module>
         <module>json-validator</module>
         <module>jsonata</module>
diff --git a/pom.xml b/pom.xml
index 05e0e37cf4..b90ac9c958 100644
--- a/pom.xml
+++ b/pom.xml
@@ -554,6 +554,7 @@
                             <Jenkinsfile>SLASHSTAR_STYLE</Jenkinsfile>
                             <Jenkinsfile.quarkus>SLASHSTAR_STYLE</Jenkinsfile.quarkus>
                             <Jenkinsfile.sonarcloud>SLASHSTAR_STYLE</Jenkinsfile.sonarcloud>
+                            <jsh>SLASHSTAR_STYLE</jsh>
                             <mjs>SLASHSTAR_STYLE</mjs>
                             <properties>CAMEL_PROPERTIES_STYLE</properties>
                             <rnc>SCRIPT_STYLE</rnc>
diff --git a/poms/bom/pom.xml b/poms/bom/pom.xml
index 997ed315ff..1abb991961 100644
--- a/poms/bom/pom.xml
+++ b/poms/bom/pom.xml
@@ -3648,6 +3648,11 @@
                     </exclusion>
                 </exclusions>
             </dependency>
+            <dependency>
+                <groupId>org.apache.camel</groupId>
+                <artifactId>camel-jsh-dsl</artifactId>
+                <version>${camel.version}</version>
+            </dependency>
             <dependency>
                 <groupId>org.apache.camel</groupId>
                 <artifactId>camel-jslt</artifactId>
@@ -7779,6 +7784,16 @@
                 <artifactId>camel-quarkus-jsch-deployment</artifactId>
                 <version>${camel-quarkus.version}</version>
             </dependency>
+            <dependency>
+                <groupId>org.apache.camel.quarkus</groupId>
+                <artifactId>camel-quarkus-jsh-dsl</artifactId>
+                <version>${camel-quarkus.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.camel.quarkus</groupId>
+                <artifactId>camel-quarkus-jsh-dsl-deployment</artifactId>
+                <version>${camel-quarkus.version}</version>
+            </dependency>
             <dependency>
                 <groupId>org.apache.camel.quarkus</groupId>
                 <artifactId>camel-quarkus-jslt</artifactId>
@@ -8954,6 +8969,16 @@
                 <artifactId>camel-quarkus-support-debezium-deployment</artifactId>
                 <version>${camel-quarkus.version}</version>
             </dependency>
+            <dependency>
+                <groupId>org.apache.camel.quarkus</groupId>
+                <artifactId>camel-quarkus-support-dsl</artifactId>
+                <version>${camel-quarkus.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.camel.quarkus</groupId>
+                <artifactId>camel-quarkus-support-dsl-deployment</artifactId>
+                <version>${camel-quarkus.version}</version>
+            </dependency>
             <dependency>
                 <groupId>org.apache.camel.quarkus</groupId>
                 <artifactId>camel-quarkus-support-google-cloud</artifactId>
diff --git a/poms/bom/src/main/generated/flattened-full-pom.xml b/poms/bom/src/main/generated/flattened-full-pom.xml
index 9776aefcb0..5ef1314731 100644
--- a/poms/bom/src/main/generated/flattened-full-pom.xml
+++ b/poms/bom/src/main/generated/flattened-full-pom.xml
@@ -3587,6 +3587,11 @@
           </exclusion>
         </exclusions>
       </dependency>
+      <dependency>
+        <groupId>org.apache.camel</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+        <artifactId>camel-jsh-dsl</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+        <version>3.20.1</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+      </dependency>
       <dependency>
         <groupId>org.apache.camel</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
         <artifactId>camel-jslt</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
@@ -7716,6 +7721,16 @@
         <artifactId>camel-quarkus-jsch-deployment</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
         <version>2.16.0-SNAPSHOT</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
       </dependency>
+      <dependency>
+        <groupId>org.apache.camel.quarkus</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+        <artifactId>camel-quarkus-jsh-dsl</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+        <version>2.16.0-SNAPSHOT</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+      </dependency>
+      <dependency>
+        <groupId>org.apache.camel.quarkus</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+        <artifactId>camel-quarkus-jsh-dsl-deployment</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+        <version>2.16.0-SNAPSHOT</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+      </dependency>
       <dependency>
         <groupId>org.apache.camel.quarkus</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
         <artifactId>camel-quarkus-jslt</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
@@ -8891,6 +8906,16 @@
         <artifactId>camel-quarkus-support-debezium-deployment</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
         <version>2.16.0-SNAPSHOT</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
       </dependency>
+      <dependency>
+        <groupId>org.apache.camel.quarkus</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+        <artifactId>camel-quarkus-support-dsl</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+        <version>2.16.0-SNAPSHOT</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+      </dependency>
+      <dependency>
+        <groupId>org.apache.camel.quarkus</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+        <artifactId>camel-quarkus-support-dsl-deployment</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+        <version>2.16.0-SNAPSHOT</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+      </dependency>
       <dependency>
         <groupId>org.apache.camel.quarkus</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
         <artifactId>camel-quarkus-support-google-cloud</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
diff --git a/poms/bom/src/main/generated/flattened-reduced-pom.xml b/poms/bom/src/main/generated/flattened-reduced-pom.xml
index 1f29d5ad79..e83b23fd6a 100644
--- a/poms/bom/src/main/generated/flattened-reduced-pom.xml
+++ b/poms/bom/src/main/generated/flattened-reduced-pom.xml
@@ -3582,6 +3582,11 @@
           </exclusion>
         </exclusions>
       </dependency>
+      <dependency>
+        <groupId>org.apache.camel</groupId>
+        <artifactId>camel-jsh-dsl</artifactId>
+        <version>3.20.1</version>
+      </dependency>
       <dependency>
         <groupId>org.apache.camel</groupId>
         <artifactId>camel-jslt</artifactId>
@@ -7711,6 +7716,16 @@
         <artifactId>camel-quarkus-jsch-deployment</artifactId>
         <version>2.16.0-SNAPSHOT</version>
       </dependency>
+      <dependency>
+        <groupId>org.apache.camel.quarkus</groupId>
+        <artifactId>camel-quarkus-jsh-dsl</artifactId>
+        <version>2.16.0-SNAPSHOT</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.camel.quarkus</groupId>
+        <artifactId>camel-quarkus-jsh-dsl-deployment</artifactId>
+        <version>2.16.0-SNAPSHOT</version>
+      </dependency>
       <dependency>
         <groupId>org.apache.camel.quarkus</groupId>
         <artifactId>camel-quarkus-jslt</artifactId>
@@ -8886,6 +8901,16 @@
         <artifactId>camel-quarkus-support-debezium-deployment</artifactId>
         <version>2.16.0-SNAPSHOT</version>
       </dependency>
+      <dependency>
+        <groupId>org.apache.camel.quarkus</groupId>
+        <artifactId>camel-quarkus-support-dsl</artifactId>
+        <version>2.16.0-SNAPSHOT</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.camel.quarkus</groupId>
+        <artifactId>camel-quarkus-support-dsl-deployment</artifactId>
+        <version>2.16.0-SNAPSHOT</version>
+      </dependency>
       <dependency>
         <groupId>org.apache.camel.quarkus</groupId>
         <artifactId>camel-quarkus-support-google-cloud</artifactId>
diff --git a/poms/bom/src/main/generated/flattened-reduced-verbose-pom.xml b/poms/bom/src/main/generated/flattened-reduced-verbose-pom.xml
index 2d312f9b17..b64268cb5f 100644
--- a/poms/bom/src/main/generated/flattened-reduced-verbose-pom.xml
+++ b/poms/bom/src/main/generated/flattened-reduced-verbose-pom.xml
@@ -3582,6 +3582,11 @@
           </exclusion>
         </exclusions>
       </dependency>
+      <dependency>
+        <groupId>org.apache.camel</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+        <artifactId>camel-jsh-dsl</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+        <version>3.20.1</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+      </dependency>
       <dependency>
         <groupId>org.apache.camel</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
         <artifactId>camel-jslt</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
@@ -7711,6 +7716,16 @@
         <artifactId>camel-quarkus-jsch-deployment</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
         <version>2.16.0-SNAPSHOT</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
       </dependency>
+      <dependency>
+        <groupId>org.apache.camel.quarkus</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+        <artifactId>camel-quarkus-jsh-dsl</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+        <version>2.16.0-SNAPSHOT</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+      </dependency>
+      <dependency>
+        <groupId>org.apache.camel.quarkus</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+        <artifactId>camel-quarkus-jsh-dsl-deployment</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+        <version>2.16.0-SNAPSHOT</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+      </dependency>
       <dependency>
         <groupId>org.apache.camel.quarkus</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
         <artifactId>camel-quarkus-jslt</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
@@ -8886,6 +8901,16 @@
         <artifactId>camel-quarkus-support-debezium-deployment</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
         <version>2.16.0-SNAPSHOT</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
       </dependency>
+      <dependency>
+        <groupId>org.apache.camel.quarkus</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+        <artifactId>camel-quarkus-support-dsl</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+        <version>2.16.0-SNAPSHOT</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+      </dependency>
+      <dependency>
+        <groupId>org.apache.camel.quarkus</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+        <artifactId>camel-quarkus-support-dsl-deployment</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+        <version>2.16.0-SNAPSHOT</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+      </dependency>
       <dependency>
         <groupId>org.apache.camel.quarkus</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
         <artifactId>camel-quarkus-support-google-cloud</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
diff --git a/tooling/scripts/test-categories.yaml b/tooling/scripts/test-categories.yaml
index 023abb356b..304ace2eed 100644
--- a/tooling/scripts/test-categories.yaml
+++ b/tooling/scripts/test-categories.yaml
@@ -208,6 +208,7 @@ group-13:
   - jira
   - java-joor-dsl
   - js-dsl
+  - jsh-dsl
   - kotlin-dsl
   - kubernetes
   - salesforce