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

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


The following commit(s) were added to refs/heads/main by this push:
     new 610d5365740 CAMEL-18151: camel-jbang - Export command for spring boot
610d5365740 is described below

commit 610d53657407fe51d72b985868280a4fc017edff
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Tue May 31 10:52:33 2022 +0200

    CAMEL-18151: camel-jbang - Export command for spring boot
---
 .../modules/ROOT/pages/camel-jbang.adoc            |  53 +---
 .../dsl/jbang/core/commands/CamelJBangMain.java    |   4 +-
 .../core/commands/{Create.java => Export.java}     |  18 +-
 .../dsl/jbang/core/commands/ExportSpringBoot.java  | 322 +++++++++++++++++++++
 .../camel/dsl/jbang/core/commands/Project.java     | 165 -----------
 .../apache/camel/dsl/jbang/core/commands/Run.java  |  21 +-
 .../jbang/core/generator/CamelJbangGenerator.java  |  33 ---
 .../dsl/jbang/core/generator/PomDependency.java    |  74 -----
 .../dsl/jbang/core/generator/PomProperty.java      |  43 ---
 .../dsl/jbang/core/generator/QuarkusGenerator.java |  64 ----
 .../core/templates/VelocityTemplateParser.java     | 115 --------
 .../src/main/resources/generator/quarkus-pom.ftl   | 259 -----------------
 .../main/resources/templates/spring-boot-main.tmpl |  13 +
 .../main/resources/templates/spring-boot-pom.tmpl  |  84 ++++++
 .../main/CommandLineDependencyDownloader.java      |   3 +-
 .../main/DependencyDownloaderClassResolver.java    |   3 +-
 .../DependencyDownloaderComponentResolver.java     |   3 +-
 .../DependencyDownloaderDataFormatResolver.java    |   3 +-
 .../camel/main/DependencyDownloaderKamelet.java    |   3 +-
 .../main/DependencyDownloaderLanguageResolver.java |   3 +-
 ...ependencyDownloaderPropertyBindingListener.java |   3 +-
 .../main/DependencyDownloaderRoutesLoader.java     |   3 +-
 .../camel/main/DependencyDownloaderStrategy.java   |   2 +-
 .../org/apache/camel/main/DownloadListener.java    |   8 +
 .../org/apache/camel/main/DownloaderHelper.java    |   7 +-
 25 files changed, 487 insertions(+), 822 deletions(-)

diff --git a/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc
index a44a2e42b4f..654a3bee8bf 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc
@@ -538,59 +538,30 @@ It is better practice specifying configurations in 
external files such as `appli
 
 You can _export_ your Camel JBang application to a traditional Java based 
project such as Spring Boot or Quarkus.
 
-=== Create Quarkus Project
+You may want to do this after you have built a prototype using Camel JBang, 
and are in need
+of a traditional Java based project with more need for Java coding, or wanting 
to use the powerful
+runtimes of Spring Boot or Quarkus.
 
-NOTE: New implementation on the way
+=== Exporting to Camel Spring Boot
 
-The `create project` command can be used to generate a Maven project. After 
running the integration with the `run` command `create project` will generate a 
Maven Quarkus project with some required dependencies that can be used as a 
starting point for complex integrations. 
+The command `export spring-boot` will export your current Camel JBang file(s) 
to a Maven based
+Spring Boot project with files organized in `src/main/` folder structure.
 
-To execute this feature run:
+For example to export to Spring Boot using the Maven groupId _com.foo_ and the 
artifactId _acme_
+and with version _1.0-SNAPSHOT_ you simply execute:
 
 [source,bash]
 ----
-jbang camel@apache/camel create project integration.java integration.yaml 
integration.xml
+camel export spring-boot --gav=com.foo:acme:1.0-SNAPSHOT
 ----
 
-This command generates a folder named CamelJBang that contains the Quarkus 
project, in order to execute it the following command can be run:
+NOTE: This will export to the _current_ directory, meaning that files are 
moved into the needed folder structure.
 
-[source,bash]
-----
-cd CamelJBang
-mvn compile quarkus:dev
-----
-
-The table below lists all the command line options configurable on the `create 
project` command:
-
-|===
-|Option |Description
-
-|name
-|The name of the Camel application (artifactId and folder)
-
-|group-id
-|The group ID of the maven project
-
-|directory
-|Directory where the project will be created
-
-|quarkus-dependency
-|Comma separated list of camel-quarkus dependencies
-
-|quarkus-bom-version
-|Override quarkus bom version in pom.xml
-
-|===
-
-==== Examples
-
-[source,bash]
-----
-jbang camel@apache/camel create project TimerRoute.java 
--quarkusDependencies=camel-quarkus-timer,camel-quarkus-log,camel-quarkus-yaml-dsl,camel-quarkus-http
 --name=TimerRouteProject
-----
+To export to another directly (copies the files) you execute:
 
 [source,bash]
 ----
-jbang camel@apache/camel create project KafkaRoute.java 
--quarkusDependencies=camel-quarkus-kafka,camel-quarkus-log 
--name=KafkaRouteProject
+camel export spring-boot --gav=com.foo:acme:1.0-SNAPSHOT --dir=../myproject
 ----
 
 == Troubleshooting
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelJBangMain.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelJBangMain.java
index 5d4b3b13ac0..84976957b85 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelJBangMain.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelJBangMain.java
@@ -45,6 +45,8 @@ public class CamelJBangMain implements Callable<Integer> {
                 .addSubcommand("build", new CommandLine(new Build(main))
                         .addSubcommand("manifests", new CommandLine(new 
Manifest(main)))
                         .addSubcommand("image", new CommandLine(new 
Image(main))))
+                .addSubcommand("export", new CommandLine(new Export(main))
+                        .addSubcommand("spring-boot", new CommandLine(new 
ExportSpringBoot(main))))
                 .addSubcommand("deploy", new CommandLine(new Deploy(main)))
                 .addSubcommand("undeploy", new CommandLine(new 
Undeploy(main)));
         /* // TODO: do not show commands that are deprecated and to be either 
removed or reworked
@@ -53,8 +55,6 @@ public class CamelJBangMain implements Callable<Integer> {
                         .addSubcommand("components", new SearchComponents())
                         .addSubcommand("languages", new SearchLanguages())
                         .addSubcommand("others", new SearchOthers()))
-                .addSubcommand("create", new CommandLine(new Create())
-                        .addSubcommand("project", new Project()));
         */
 
         commandLine.getCommandSpec().versionProvider(() -> {
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Create.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Export.java
similarity index 72%
rename from 
dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Create.java
rename to 
dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Export.java
index b0d4ce4787d..28d42a4c237 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Create.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Export.java
@@ -16,24 +16,20 @@
  */
 package org.apache.camel.dsl.jbang.core.commands;
 
-import java.util.concurrent.Callable;
-
 import picocli.CommandLine;
 import picocli.CommandLine.Command;
-import picocli.CommandLine.Option;
 
-@Command(name = "create", description = "Creates Maven Project (use --help)")
-@Deprecated
-class Create implements Callable<Integer> {
-    //CHECKSTYLE:OFF
-    @Option(names = { "-h", "--help" }, usageHelp = true, description = 
"Display the help and sub-commands")
-    private boolean helpRequested = false;
-    //CHECKSTYLE:ON
+@Command(name = "export",
+         description = "Export to other runtimes such as Spring Boot or 
Quarkus (use --help to see sub commands)")
+class Export extends CamelCommand {
+
+    public Export(CamelJBangMain main) {
+        super(main);
+    }
 
     @Override
     public Integer call() throws Exception {
         new CommandLine(this).execute("--help");
-
         return 0;
     }
 }
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportSpringBoot.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportSpringBoot.java
new file mode 100644
index 00000000000..48e82859d81
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportSpringBoot.java
@@ -0,0 +1,322 @@
+/*
+ * 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.dsl.jbang.core.commands;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.stream.Collectors;
+
+import org.apache.camel.catalog.CamelCatalog;
+import org.apache.camel.catalog.DefaultCamelCatalog;
+import org.apache.camel.main.MavenGav;
+import org.apache.camel.util.FileUtil;
+import org.apache.camel.util.IOHelper;
+import org.apache.camel.util.OrderedProperties;
+import org.apache.camel.util.StringHelper;
+import picocli.CommandLine;
+
+@CommandLine.Command(name = "spring-boot", description = "Export as Spring 
Boot project")
+class ExportSpringBoot extends CamelCommand {
+
+    private static final String BUILD_DIR = ".camel-jbang/work";
+
+    private static final String[] SETTINGS_PROP_SOURCE_KEYS = new String[] {
+            "camel.main.routesIncludePattern",
+            "camel.component.properties.location",
+            "camel.component.kamelet.location",
+            "camel.jbang.classpathFiles"
+    };
+
+    @CommandLine.Option(names = { "--gav" }, description = "The Maven 
group:artifact:version", required = true)
+    private String gav;
+
+    @CommandLine.Option(names = { "--main-classname" },
+                        description = "The class name of the Camel Spring Boot 
application class",
+                        defaultValue = "CamelApplication")
+    private String mainClassname;
+
+    @CommandLine.Option(names = { "--java-version" }, description = "Java 
version (11 or 17)",
+                        defaultValue = "11")
+    private String javaVersion;
+
+    @CommandLine.Option(names = { "--spring-boot-version" }, description = 
"Spring Boot version",
+                        defaultValue = "2.6.8")
+    private String springBootVersion;
+
+    @CommandLine.Option(names = { "-dir", "--directory" }, description = 
"Directory where the project will be exported",
+                        defaultValue = ".")
+    private String exportDir;
+
+    @CommandLine.Option(names = { "--fresh" }, description = "Make sure we use 
fresh (i.e. non-cached) resources")
+    private boolean fresh;
+
+    public ExportSpringBoot(CamelJBangMain main) {
+        super(main);
+    }
+
+    @Override
+    public Integer call() throws Exception {
+        String[] ids = gav.split(":");
+        if (ids.length != 3) {
+            System.out.println("--gav must be in syntax: 
groupId:artifactId:version");
+            return 1;
+        }
+
+        File profile = new File(getProfile() + ".properties");
+
+        // the settings file has information what to export
+        File settings = new File(Run.WORK_DIR + "/" + Run.RUN_SETTINGS_FILE);
+        if (fresh || !settings.exists()) {
+            // allow to automatic build
+            System.out.println("Generating fresh run data");
+            int silent = runSilently();
+            if (silent != 0) {
+                return silent;
+            }
+        } else {
+            System.out.println("Reusing existing run data");
+        }
+
+        System.out.println("Exporting as Spring Boot project to: " + 
exportDir);
+
+        // use a temporary work dir
+        File buildDir = new File(BUILD_DIR);
+        FileUtil.removeDir(buildDir);
+        buildDir.mkdirs();
+
+        // copy source files
+        String packageName = ids[0] + "." + ids[1];
+        File srcJavaDir = new File(BUILD_DIR, "src/main/java/" + 
packageName.replace('.', '/'));
+        srcJavaDir.mkdirs();
+        File srcResourcesDir = new File(BUILD_DIR, "src/main/resources");
+        srcResourcesDir.mkdirs();
+        copySourceFiles(settings, srcJavaDir, srcResourcesDir, packageName);
+        // copy from settings to profile
+        copySettingsAndProfile(settings, profile, srcResourcesDir);
+        // create main class
+        createMainClassSource(srcJavaDir, packageName, mainClassname);
+        // gather dependencies
+        Set<String> deps = resolveDependencies(settings);
+        // create pom
+        createPom(new File(BUILD_DIR, "pom.xml"), deps);
+
+        // move work dir to the export dir
+        if (!exportDir.equals(".")) {
+            // create the dir and copy over all files from work dir
+            File target = new File(exportDir);
+            target.mkdirs();
+            Files.move(new File(BUILD_DIR).toPath(), target.toPath(), 
StandardCopyOption.ATOMIC_MOVE);
+        }
+        // TODO: If output is same folder (eg dot) then files should be moved 
instead of copy (or we delete all and move from work dir)
+
+        return 0;
+    }
+
+    private void createPom(File pom, Set<String> deps) throws Exception {
+        String[] ids = gav.split(":");
+
+        InputStream is = 
ExportSpringBoot.class.getClassLoader().getResourceAsStream("templates/spring-boot-pom.tmpl");
+        String context = IOHelper.loadText(is);
+        IOHelper.close(is);
+
+        CamelCatalog catalog = new DefaultCamelCatalog();
+        String camelVersion = catalog.getCatalogVersion();
+
+        context = context.replaceFirst("\\{\\{ \\.GroupId }}", ids[0]);
+        context = context.replaceFirst("\\{\\{ \\.ArtifactId }}", ids[1]);
+        context = context.replaceFirst("\\{\\{ \\.Version }}", ids[2]);
+        context = context.replaceAll("\\{\\{ \\.SpringBootVersion }}", 
springBootVersion);
+        context = context.replaceFirst("\\{\\{ \\.JavaVersion }}", 
javaVersion);
+        context = context.replaceFirst("\\{\\{ \\.CamelVersion }}", 
camelVersion);
+
+        StringBuilder sb = new StringBuilder();
+        for (String dep : deps) {
+            MavenGav gav = MavenGav.parseGav(null, dep);
+            String gid = gav.getGroupId();
+            String aid = gav.getArtifactId();
+            String v = gav.getVersion();
+            // transform to camel-spring-boot starter GAV
+            if ("org.apache.camel".equals(gid)) {
+                gid = "org.apache.camel.springboot";
+                aid = aid + "-starter";
+                v = null;
+            }
+            sb.append("        <dependency>\n");
+            sb.append("            
<groupId>").append(gid).append("</groupId>\n");
+            sb.append("            
<artifactId>").append(aid).append("</artifactId>\n");
+            if (v != null) {
+                sb.append("            
<version>").append(v).append("</version>\n");
+            }
+            sb.append("        </dependency>\n");
+        }
+        context = context.replaceFirst("\\{\\{ \\.CamelDependencies }}", 
sb.toString());
+
+        IOHelper.writeText(context, new FileOutputStream(pom, false));
+    }
+
+    private Set<String> resolveDependencies(File settings) throws Exception {
+        Set<String> answer = new TreeSet<>();
+        List<String> lines = Files.readAllLines(settings.toPath());
+        for (String line : lines) {
+            if (line.startsWith("dependency=")) {
+                String v = StringHelper.after(line, "dependency=");
+                // skip core-languages and java-joor as we let spring boot 
compile
+                boolean skip = v == null || 
v.contains("org.apache.camel:camel-core-languages")
+                        || v.contains("org.apache.camel:camel-java-joor-dsl");
+                if (!skip) {
+                    answer.add(v);
+                }
+            }
+        }
+        return answer;
+    }
+
+    private void createMainClassSource(File srcJavaDir, String packageName, 
String mainClassname) throws Exception {
+        InputStream is = 
ExportSpringBoot.class.getClassLoader().getResourceAsStream("templates/spring-boot-main.tmpl");
+        String context = IOHelper.loadText(is);
+        IOHelper.close(is);
+
+        context = context.replaceFirst("\\{\\{ \\.PackageName }}", 
packageName);
+        context = context.replaceAll("\\{\\{ \\.MainClassname }}", 
mainClassname);
+        IOHelper.writeText(context, new FileOutputStream(srcJavaDir + "/" + 
mainClassname + ".java", false));
+    }
+
+    private Integer runSilently() throws Exception {
+        Run run = new Run(getMain());
+        Integer code = run.runSilent();
+        return code;
+    }
+
+    private void copySourceFiles(File settings, File srcJavaDir, File 
srcResourcesDir, String packageName) throws Exception {
+        // read the settings file and find the files to copy
+        OrderedProperties prop = new OrderedProperties();
+        prop.load(new FileInputStream(settings));
+
+        for (String k : SETTINGS_PROP_SOURCE_KEYS) {
+            String files = prop.getProperty(k);
+            if (files != null) {
+                for (String f : files.split(",")) {
+                    String scheme = getScheme(f);
+                    if (scheme != null) {
+                        f = f.substring(scheme.length() + 1);
+                    }
+                    String ext = FileUtil.onlyExt(f, true);
+                    boolean java = "java".equals(ext);
+                    File target = java ? srcJavaDir : srcResourcesDir;
+                    File source = new File(f);
+                    File out = new File(target, source.getName());
+                    safeCopy(source, out, true);
+                    if (java) {
+                        // need to append package name in java source file
+                        List<String> lines = Files.readAllLines(out.toPath());
+                        lines.add(0, "");
+                        lines.add(0, "package " + packageName + ";");
+                        FileOutputStream fos = new FileOutputStream(out);
+                        for (String line : lines) {
+                            if (line.startsWith("public class")
+                                    && (line.contains("RouteBuilder") || 
line.contains("EndpointRouteBuilder"))) {
+                                fos.write("import 
org.springframework.stereotype.Component;\n\n"
+                                        .getBytes(StandardCharsets.UTF_8));
+                                
fos.write("@Component\n".getBytes(StandardCharsets.UTF_8));
+                            }
+                            fos.write(line.getBytes(StandardCharsets.UTF_8));
+                            fos.write("\n".getBytes(StandardCharsets.UTF_8));
+                        }
+                        IOHelper.close(fos);
+                    }
+                }
+            }
+        }
+    }
+
+    private void copySettingsAndProfile(File settings, File profile, File 
targetDir) throws Exception {
+        OrderedProperties prop = new OrderedProperties();
+        prop.load(new FileInputStream(settings));
+        OrderedProperties prop2 = new OrderedProperties();
+        if (profile.exists()) {
+            prop2.load(new FileInputStream(profile));
+        }
+
+        for (Map.Entry<Object, Object> entry : prop.entrySet()) {
+            String key = entry.getKey().toString();
+            boolean skip = "camel.main.routesCompileDirectory".equals(key) || 
"camel.main.routesReloadEnabled".equals(key);
+            if (!skip && key.startsWith("camel.main")) {
+                prop2.put(entry.getKey(), entry.getValue());
+            }
+        }
+
+        // camel.main.x should be renamed to camel.springboot.x
+        OrderedProperties prop3 = new OrderedProperties();
+        for (Map.Entry<Object, Object> entry : prop2.entrySet()) {
+            String key = entry.getKey().toString();
+            if (key.startsWith("camel.main.")) {
+                key = "camel.springboot." + key.substring(11);
+            }
+            prop3.put(key, entry.getValue());
+        }
+
+        FileOutputStream fos = new FileOutputStream(new File(targetDir, 
profile.getName()), false);
+        for (Map.Entry<Object, Object> entry : prop3.entrySet()) {
+            String k = entry.getKey().toString();
+            String v = entry.getValue().toString();
+            // files are now loaded in classpath
+            v = v.replaceAll("file:", "classpath:");
+            if ("camel.springboot.routesIncludePattern".equals(k)) {
+                // camel.main.routesIncludePattern should remove all .java as 
we use spring boot to load them
+                v = Arrays.stream(v.split(","))
+                        .filter(n -> !n.endsWith(".java"))
+                        .collect(Collectors.joining(","));
+            }
+            String line = k + "=" + v;
+            fos.write(line.getBytes(StandardCharsets.UTF_8));
+            fos.write("\n".getBytes(StandardCharsets.UTF_8));
+        }
+        IOHelper.close(fos);
+    }
+
+    private static void safeCopy(File source, File target, boolean override) 
throws Exception {
+        if (!source.exists()) {
+            return;
+        }
+
+        if (!target.exists()) {
+            Files.copy(source.toPath(), target.toPath());
+        } else if (override) {
+            Files.copy(source.toPath(), target.toPath(),
+                    StandardCopyOption.REPLACE_EXISTING);
+        }
+    }
+
+    private static String getScheme(String name) {
+        int pos = name.indexOf(":");
+        if (pos != -1) {
+            return name.substring(0, pos);
+        }
+        return null;
+    }
+
+}
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Project.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Project.java
deleted file mode 100644
index 6d041040ee1..00000000000
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Project.java
+++ /dev/null
@@ -1,165 +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.dsl.jbang.core.commands;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.Writer;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-import java.util.concurrent.Callable;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Stream;
-
-import freemarker.template.Configuration;
-import freemarker.template.Template;
-import freemarker.template.TemplateException;
-import freemarker.template.TemplateExceptionHandler;
-import org.apache.camel.dsl.jbang.core.generator.CamelJbangGenerator;
-import org.apache.camel.dsl.jbang.core.generator.QuarkusGenerator;
-import picocli.CommandLine;
-
-@CommandLine.Command(name = "create-project", description = "Creates 
Camel-Quarkus project")
-@Deprecated
-public class Project implements Callable<Integer> {
-
-    private static final String PACKAGE_REGEX = 
"package\\s+([a-zA_Z_][\\.\\w]*);";
-    private static final Pattern PACKAGE_PATTERN = 
Pattern.compile(PACKAGE_REGEX);
-    @CommandLine.Parameters(description = "The Camel file(s) to include in the 
created project", arity = "1")
-    private String[] files;
-    @CommandLine.Option(names = { "-h", "--help" }, usageHelp = true, 
description = "Display the help and sub-commands")
-    private boolean helpRequested;
-    @CommandLine.Option(names = { "-n", "--name" }, description = "The name of 
the Camel application",
-                        defaultValue = "CamelJBang")
-    private String name;
-    @CommandLine.Option(names = { "-g", "--group-id" }, description = "The 
group ID of the maven project",
-                        defaultValue = "org.apache.camel.jbang")
-    private String groupId;
-    @CommandLine.Option(names = { "-d", "--directory" }, description = 
"Directory where the project will be created",
-                        defaultValue = ".")
-    private String baseDirectory;
-    @CommandLine.Option(names = "--quarkus-dependency", description = "Comma 
separated list of camel-quarkus dependencies",
-                        defaultValue = 
"camel-quarkus-timer,camel-quarkus-log,camel-quarkus-yaml-dsl,camel-quarkus-kamelet,org.apache.camel.kamelets:camel-kamelets-catalog:0.6.0")
-    private String quarkusDependencies;
-    @CommandLine.Option(names = "--quarkus-bom-version", description = 
"Override quarkus bom version in pom.xml",
-                        defaultValue = "2.6.0.Final")
-    private String quarkusBomVersion;
-
-    private CamelJbangGenerator generator;
-    private Path resourcesFolder = Paths.get("src", "main", "resources");
-    private Path sourcesFolder = Paths.get("src", "main", "java");
-    private Path routesFolder = resourcesFolder.resolve("routes");
-
-    @Override
-    public Integer call() throws Exception {
-        generator = new 
QuarkusGenerator(Arrays.asList(quarkusDependencies.split(",")), 
quarkusBomVersion);
-
-        File baseDir = new File(baseDirectory);
-        createDirectory(baseDir);
-
-        Path projectPath = Paths.get(baseDirectory, name);
-        File projectDir = projectPath.toFile();
-        createDirectory(projectDir);
-
-        System.out.println(name + " project will be generated in " + 
projectDir.getAbsolutePath());
-
-        createProjectStructure(projectPath);
-
-        for (String file : files) {
-            if (!file.endsWith(".java")) {
-                Files.copy(Paths.get(file), 
projectPath.resolve(routesFolder).resolve(Paths.get(file).getFileName()));
-            } else {
-                String packageName;
-                try (Stream<String> stream = Files.lines(Paths.get(file))
-                        .map(this::getPackage)
-                        .filter(Objects::nonNull)) {
-                    packageName = stream
-                            .findFirst()
-                            .orElse("");
-                }
-                try {
-                    Path packageDirectory
-                            = 
projectPath.resolve(sourcesFolder).resolve(packageName.replace(".", 
File.separator));
-                    if (!packageDirectory.toFile().exists()) {
-                        createDirectory(packageDirectory.toFile());
-                    }
-
-                    Files.copy(Paths.get(file),
-                            
packageDirectory.resolve(Paths.get(file).getFileName()));
-                } catch (IOException e) {
-                    throw new RuntimeException(e);
-                }
-            }
-        }
-
-        return 0;
-    }
-
-    private void createProjectStructure(Path projectPath) throws IOException {
-        Path javaSourcesPath = projectPath.resolve(sourcesFolder);
-        createDirectory(javaSourcesPath.toFile());
-        Path resourcesPath = projectPath.resolve(resourcesFolder);
-        createDirectory(resourcesPath.toFile());
-        Path routes = projectPath.resolve(routesFolder);
-        createDirectory(routes.toFile());
-
-        // Create application.properties
-        Files.write(projectPath.resolve(generator.getPropertyFileLocation()),
-                generator.getPropertyFileContent(name).getBytes());
-
-        // Create pom.xml
-        Map root = new HashMap<String, Object>();
-        root.put("name", name);
-        root.put("groupId", groupId);
-        root.put("pomProperties", generator.getPomProperties());
-        root.put("pomDependencies", generator.getPomDependencies());
-
-        Configuration cfg = new 
Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
-        cfg.setClassForTemplateLoading(this.getClass(), "/generator");
-        
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
-
-        Template template = cfg.getTemplate(generator.getTemplate());
-
-        try (Writer fileWriter = new 
FileWriter(projectPath.resolve("pom.xml").toFile())) {
-            template.process(root, fileWriter);
-        } catch (TemplateException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    private String getPackage(String fileContent) {
-        Matcher matcher = PACKAGE_PATTERN.matcher(fileContent);
-        if (matcher.find()) {
-            return matcher.group(1);
-        }
-
-        return null;
-    }
-
-    private void createDirectory(File directory) {
-        if (!directory.exists()) {
-            directory.mkdirs();
-        }
-    }
-}
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java
index d0166dc8457..6c144f5ca51 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java
@@ -51,6 +51,7 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.dsl.jbang.core.common.RuntimeUtil;
 import org.apache.camel.generator.openapi.RestDslGenerator;
 import org.apache.camel.impl.lw.LightweightCamelContext;
+import org.apache.camel.main.DownloadListener;
 import org.apache.camel.main.KameletMain;
 import org.apache.camel.support.ResourceHelper;
 import org.apache.camel.util.FileUtil;
@@ -307,11 +308,20 @@ class Run extends CamelCommand {
         final KameletMain main = createMainInstance();
 
         final Set<String> downloaded = new HashSet<>();
-        main.setDownloadListener((groupId, artifactId, version) -> {
-            String line = "mvn:" + groupId + ":" + artifactId + ":" + version;
-            if (!downloaded.contains(line)) {
-                writeSettings("dependency", line);
-                downloaded.add(line);
+        main.setDownloadListener(new DownloadListener() {
+            @Override
+            public void onDownloadDependency(String groupId, String 
artifactId, String version) {
+                String line = "mvn:" + groupId + ":" + artifactId + ":" + 
version;
+                if (!downloaded.contains(line)) {
+                    writeSettings("dependency", line);
+                    downloaded.add(line);
+                }
+            }
+
+            @Override
+            public void onAlreadyDownloadedDependency(String groupId, String 
artifactId, String version) {
+                // we want to register everything
+                onDownloadDependency(groupId, artifactId, version);
             }
         });
         main.setAppName("Apache Camel (JBang)");
@@ -524,6 +534,7 @@ class Run extends CamelCommand {
             } else {
                 loc = locations.toString();
             }
+            // TODO: remove duplicates in loc
             main.addInitialProperty("camel.component.properties.location", 
loc);
             writeSettings("camel.component.properties.location", loc);
         }
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/generator/CamelJbangGenerator.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/generator/CamelJbangGenerator.java
deleted file mode 100644
index a7709e4d119..00000000000
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/generator/CamelJbangGenerator.java
+++ /dev/null
@@ -1,33 +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.dsl.jbang.core.generator;
-
-import java.nio.file.Path;
-import java.util.List;
-
-public interface CamelJbangGenerator {
-
-    Path getPropertyFileLocation();
-
-    String getPropertyFileContent(String name);
-
-    List<PomProperty> getPomProperties();
-
-    String getTemplate();
-
-    List<PomDependency> getPomDependencies();
-}
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/generator/PomDependency.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/generator/PomDependency.java
deleted file mode 100644
index 33dcf9f0557..00000000000
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/generator/PomDependency.java
+++ /dev/null
@@ -1,74 +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.dsl.jbang.core.generator;
-
-public class PomDependency {
-    private String groupId;
-    private String artifactId;
-    private String version;
-
-    public PomDependency(String artifactId) {
-        this.artifactId = artifactId;
-        this.groupId = "org.apache.camel.quarkus";
-    }
-
-    public PomDependency(String groupId, String artifactId) {
-        this.groupId = groupId;
-        this.artifactId = artifactId;
-    }
-
-    public PomDependency(String groupId, String artifactId, String version) {
-        this.groupId = groupId;
-        this.artifactId = artifactId;
-        this.version = version;
-    }
-
-    public static PomDependency of(String dependency) {
-        String[] gav = dependency.split(":");
-        if (gav.length == 3) {
-            return new PomDependency(gav[0], gav[1], gav[2]);
-        } else if (gav.length == 2) {
-            return new PomDependency(gav[0], gav[1]);
-        } else {
-            return new PomDependency(dependency);
-        }
-    }
-
-    public String getVersion() {
-        return version;
-    }
-
-    public void setVersion(String version) {
-        this.version = version;
-    }
-
-    public String getGroupId() {
-        return groupId;
-    }
-
-    public void setGroupId(String groupId) {
-        this.groupId = groupId;
-    }
-
-    public String getArtifactId() {
-        return artifactId;
-    }
-
-    public void setArtifactId(String artifactId) {
-        this.artifactId = artifactId;
-    }
-}
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/generator/PomProperty.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/generator/PomProperty.java
deleted file mode 100644
index 295549bf687..00000000000
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/generator/PomProperty.java
+++ /dev/null
@@ -1,43 +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.dsl.jbang.core.generator;
-
-public class PomProperty {
-    private String key;
-    private String value;
-
-    public PomProperty(String key, String value) {
-        this.key = key;
-        this.value = value;
-    }
-
-    public String getKey() {
-        return key;
-    }
-
-    public void setKey(String key) {
-        this.key = key;
-    }
-
-    public String getValue() {
-        return value;
-    }
-
-    public void setValue(String value) {
-        this.value = value;
-    }
-}
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/generator/QuarkusGenerator.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/generator/QuarkusGenerator.java
deleted file mode 100644
index a139d416785..00000000000
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/generator/QuarkusGenerator.java
+++ /dev/null
@@ -1,64 +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.dsl.jbang.core.generator;
-
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.List;
-import java.util.stream.Collectors;
-
-public class QuarkusGenerator implements CamelJbangGenerator {
-
-    private final List<String> dependencies;
-    private final String bomVersion;
-
-    public QuarkusGenerator(List<String> dependencies, String bomVersion) {
-        this.dependencies = dependencies;
-        this.bomVersion = bomVersion;
-    }
-
-    @Override
-    public Path getPropertyFileLocation() {
-        return Paths.get("src", "main", "resources", "application.properties");
-    }
-
-    @Override
-    public String getPropertyFileContent(String name) {
-        StringBuilder sb = new StringBuilder();
-        sb.append("quarkus.banner.enabled = false\n");
-        sb.append("quarkus.log.file.enable = true\n");
-        sb.append("camel.context.name = ").append(name).append("\n");
-        sb.append("camel.main.routes-include-pattern = classpath:routes/*");
-        return sb.toString();
-    }
-
-    @Override
-    public List<PomProperty> getPomProperties() {
-        return List.of(new PomProperty("quarkus.platform.version", 
bomVersion));
-    }
-
-    public String getTemplate() {
-        return "quarkus-pom.ftl";
-    }
-
-    @Override
-    public List<PomDependency> getPomDependencies() {
-        return dependencies.stream()
-                .map(PomDependency::of)
-                .collect(Collectors.toList());
-    }
-}
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/templates/VelocityTemplateParser.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/templates/VelocityTemplateParser.java
deleted file mode 100644
index 094351a73f4..00000000000
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/templates/VelocityTemplateParser.java
+++ /dev/null
@@ -1,115 +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.dsl.jbang.core.templates;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Properties;
-
-import org.apache.camel.CamelException;
-import org.apache.camel.dsl.jbang.core.api.TemplateParser;
-import org.apache.camel.dsl.jbang.core.common.exceptions.ResourceAlreadyExists;
-import org.apache.camel.util.ObjectHelper;
-import org.apache.velocity.Template;
-import org.apache.velocity.VelocityContext;
-import org.apache.velocity.app.Velocity;
-import org.apache.velocity.exception.MethodInvocationException;
-import org.apache.velocity.exception.ParseErrorException;
-import org.apache.velocity.exception.ResourceNotFoundException;
-import org.apache.velocity.runtime.RuntimeConstants;
-
-public class VelocityTemplateParser implements TemplateParser {
-    private final Properties properties = new Properties();
-
-    public VelocityTemplateParser(File templateDir, String propertiesFile) 
throws IOException {
-        this(templateDir, new File(propertiesFile));
-    }
-
-    public VelocityTemplateParser(File templateDir, File propertiesFile) 
throws IOException {
-        initializeTemplateEngine(templateDir);
-
-        try (FileReader propertiesReader = new FileReader(propertiesFile)) {
-            properties.load(propertiesReader);
-        }
-    }
-
-    private void initializeTemplateEngine(File templateDir) {
-        Properties props = new Properties();
-
-        props.setProperty(RuntimeConstants.RESOURCE_LOADER, "file");
-
-        props.put("resource.loader.file.path", templateDir.getAbsolutePath());
-
-        Velocity.init(props);
-    }
-
-    private void overridePropertyList(VelocityContext context, Properties 
properties, String requiredKameletProperties) {
-        String requiredPropertyList = 
properties.getProperty(requiredKameletProperties);
-
-        if (ObjectHelper.isNotEmpty(requiredPropertyList)) {
-            context.put(requiredKameletProperties, 
requiredPropertyList.split(","));
-        }
-    }
-
-    @Override
-    public void parse(String templateFileName, Writer writer) throws 
CamelException {
-        VelocityContext context = new VelocityContext();
-
-        try {
-            loadTemplateProperties(context);
-        } catch (IOException e) {
-            throw new CamelException("Unable to load the template properties", 
e);
-        }
-
-        try {
-            Template template = Velocity.getTemplate(templateFileName);
-
-            template.merge(context, writer);
-        } catch (ResourceNotFoundException rnfe) {
-            throw new CamelException("Could not find the template to parse", 
rnfe);
-        } catch (ParseErrorException pee) {
-            throw new CamelException("Failed parsing the template", pee);
-        } catch (MethodInvocationException mie) {
-            throw new CamelException("Method call within the templated has 
failed", mie);
-        } catch (Exception e) {
-            throw new CamelException("Unspecified error while loading, parsing 
or processing the template", e);
-        }
-    }
-
-    private void loadTemplateProperties(VelocityContext context) throws 
IOException {
-        properties.forEach((k, v) -> context.put(k.toString(), v));
-
-        overridePropertyList(context, properties, "kameletProperties");
-        overridePropertyList(context, properties, "requiredKameletProperties");
-        overridePropertyList(context, properties, "kameletBeans");
-        overridePropertyList(context, properties, "fromParameters");
-        overridePropertyList(context, properties, "toParameters");
-    }
-
-    public File getOutputFile(File outputDir) throws ResourceAlreadyExists {
-        String outputFileName = properties.getProperty("kameletMetadataName") 
+ ".kamelet.yaml";
-
-        File outputFile = new File(outputDir, outputFileName);
-        if (outputFile.exists()) {
-            throw new ResourceAlreadyExists(outputFile);
-        }
-
-        return outputFile;
-    }
-}
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/resources/generator/quarkus-pom.ftl 
b/dsl/camel-jbang/camel-jbang-core/src/main/resources/generator/quarkus-pom.ftl
deleted file mode 100644
index 6242c8d90d5..00000000000
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/resources/generator/quarkus-pom.ftl
+++ /dev/null
@@ -1,259 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<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>
-
-       <artifactId>${name}</artifactId>
-       <groupId>${groupId}</groupId>
-       <version>1.0.0-SNAPSHOT</version>
-
-       <name>${name}</name>
-
-       <properties>
-               <#list pomProperties as property>
-        <${property.key}>${property.value}</${property.key}>
-        </#list>
-               
<camel-quarkus.platform.version>${r"${quarkus.platform.version}"}</camel-quarkus.platform.version>
-
-               
<quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
-               
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
-               
<camel-quarkus.platform.group-id>${r"${quarkus.platform.group-id}"}</camel-quarkus.platform.group-id>
-               
<camel-quarkus.platform.artifact-id>quarkus-camel-bom</camel-quarkus.platform.artifact-id>
-
-               
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-               
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
-               <maven.compiler.target>11</maven.compiler.target>
-               <maven.compiler.source>11</maven.compiler.source>
-               
<maven.compiler.testTarget>${r"${maven.compiler.target}"}</maven.compiler.testTarget>
-               
<maven.compiler.testSource>${r"${maven.compiler.source}"}</maven.compiler.testSource>
-
-               
<formatter-maven-plugin.version>2.17.1</formatter-maven-plugin.version>
-               
<impsort-maven-plugin.version>1.3.2</impsort-maven-plugin.version>
-               
<maven-compiler-plugin.version>3.8.0</maven-compiler-plugin.version>
-               <maven-jar-plugin.version>3.2.0</maven-jar-plugin.version>
-               
<maven-resources-plugin.version>3.1.0</maven-resources-plugin.version>
-               
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
-               <mycila-license.version>3.0</mycila-license.version>
-       </properties>
-
-       <dependencyManagement>
-               <dependencies>
-                       <!-- Import BOM -->
-                       <dependency>
-                               
<groupId>${r"${quarkus.platform.group-id}"}</groupId>
-                               
<artifactId>${r"${quarkus.platform.artifact-id}"}</artifactId>
-                               
<version>${r"${quarkus.platform.version}"}</version>
-                               <type>pom</type>
-                               <scope>import</scope>
-                       </dependency>
-                       <dependency>
-                               
<groupId>${r"${camel-quarkus.platform.group-id}"}</groupId>
-                               
<artifactId>${r"${camel-quarkus.platform.artifact-id}"}</artifactId>
-                               
<version>${r"${camel-quarkus.platform.version}"}</version>
-                               <type>pom</type>
-                               <scope>import</scope>
-                       </dependency>
-               </dependencies>
-       </dependencyManagement>
-
-       <dependencies>
-               <#list pomDependencies as dependency>
-               <dependency>
-                       <groupId>${dependency.groupId}</groupId>
-                       <artifactId>${dependency.artifactId}</artifactId>
-                       <#if dependency.version??>
-                       <version>${dependency.version}</version>
-            </#if>
-               </dependency>
-               </#list>
-
-               <!-- Test -->
-               <dependency>
-                       <groupId>io.quarkus</groupId>
-                       <artifactId>quarkus-junit5</artifactId>
-                       <scope>test</scope>
-               </dependency>
-               <dependency>
-                       <groupId>org.awaitility</groupId>
-                       <artifactId>awaitility</artifactId>
-                       <scope>test</scope>
-               </dependency>
-       </dependencies>
-
-       <build>
-               <pluginManagement>
-                       <plugins>
-
-                               <plugin>
-                                       
<groupId>net.revelc.code.formatter</groupId>
-                                       
<artifactId>formatter-maven-plugin</artifactId>
-                                       
<version>${r"${formatter-maven-plugin.version}"}</version>
-                               </plugin>
-
-                               <plugin>
-                                       <groupId>net.revelc.code</groupId>
-                                       
<artifactId>impsort-maven-plugin</artifactId>
-                                       
<version>${r"${impsort-maven-plugin.version}"}</version>
-                                       <configuration>
-                                               
<groups>java.,javax.,org.w3c.,org.xml.,junit.</groups>
-                                               
<removeUnused>true</removeUnused>
-                                               <staticAfter>true</staticAfter>
-                                               
<staticGroups>java.,javax.,org.w3c.,org.xml.,junit.</staticGroups>
-                                       </configuration>
-                               </plugin>
-
-                               <plugin>
-                                       
<groupId>org.apache.maven.plugins</groupId>
-                                       
<artifactId>maven-compiler-plugin</artifactId>
-                                       
<version>${r"${maven-compiler-plugin.version}"}</version>
-                                       <configuration>
-                                               
<showDeprecation>true</showDeprecation>
-                                               
<showWarnings>true</showWarnings>
-                                               <compilerArgs>
-                                                       
<arg>-Xlint:unchecked</arg>
-                                               </compilerArgs>
-                                       </configuration>
-                               </plugin>
-
-                               <plugin>
-                                       
<groupId>org.apache.maven.plugins</groupId>
-                                       
<artifactId>maven-surefire-plugin</artifactId>
-                                       
<version>${r"${maven-surefire-plugin.version}"}</version>
-                                       <configuration>
-                                               
<failIfNoTests>false</failIfNoTests>
-                                               <systemProperties>
-                                                       
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
-                                               </systemProperties>
-                                       </configuration>
-                               </plugin>
-
-                               <plugin>
-                                       
<groupId>${r"${quarkus.platform.group-id}"}</groupId>
-                                       
<artifactId>quarkus-maven-plugin</artifactId>
-                                       
<version>${r"${quarkus.platform.version}"}</version>
-                               </plugin>
-
-                               <plugin>
-                                       
<groupId>org.apache.maven.plugins</groupId>
-                                       
<artifactId>maven-failsafe-plugin</artifactId>
-                                       
<version>${r"${maven-surefire-plugin.version}"}</version>
-                               </plugin>
-
-                               <plugin>
-                                       
<groupId>org.apache.maven.plugins</groupId>
-                                       
<artifactId>maven-jar-plugin</artifactId>
-                                       
<version>${r"${maven-jar-plugin.version}"}</version>
-                               </plugin>
-
-                               <plugin>
-                                       <groupId>com.mycila</groupId>
-                                       
<artifactId>license-maven-plugin</artifactId>
-                                       
<version>${r"${mycila-license.version}"}</version>
-                                       <configuration>
-                                               
<failIfUnknown>true</failIfUnknown>
-                                               
<header>${r"${maven.multiModuleProjectDirectory}"}/header.txt</header>
-                                               <excludes>
-                                                       
<exclude>**/*.adoc</exclude>
-                                                       
<exclude>**/*.txt</exclude>
-                                                       
<exclude>**/LICENSE.txt</exclude>
-                                                       
<exclude>**/LICENSE</exclude>
-                                                       
<exclude>**/NOTICE.txt</exclude>
-                                                       
<exclude>**/NOTICE</exclude>
-                                                       
<exclude>**/README</exclude>
-                                                       
<exclude>**/pom.xml.versionsBackup</exclude>
-                                               </excludes>
-                                               <mapping>
-                                                       
<java>SLASHSTAR_STYLE</java>
-                                                       
<properties>CAMEL_PROPERTIES_STYLE</properties>
-                                                       <kt>SLASHSTAR_STYLE</kt>
-                                               </mapping>
-                                               <headerDefinitions>
-                                                       
<headerDefinition>${r"${maven.multiModuleProjectDirectory}"}/license-properties-headerdefinition.xml</headerDefinition>
-                                               </headerDefinitions>
-                                       </configuration>
-                               </plugin>
-                       </plugins>
-               </pluginManagement>
-
-               <plugins>
-                       <plugin>
-                               
<groupId>${r"${quarkus.platform.group-id}"}</groupId>
-                               <artifactId>quarkus-maven-plugin</artifactId>
-                               <executions>
-                                       <execution>
-                                               <id>build</id>
-                                               <goals>
-                                                       <goal>build</goal>
-                                               </goals>
-                                       </execution>
-                               </executions>
-                               <configuration>
-                                       
<workingDir>${r"${project.basedir}"}</workingDir>
-                               </configuration>
-                       </plugin>
-
-                       <plugin>
-                               <groupId>net.revelc.code.formatter</groupId>
-                               <artifactId>formatter-maven-plugin</artifactId>
-                               <executions>
-                                       <execution>
-                                               <id>format</id>
-                                               <goals>
-                                                       <goal>format</goal>
-                                               </goals>
-                                               <phase>process-sources</phase>
-                                       </execution>
-                               </executions>
-                       </plugin>
-
-                       <plugin>
-                               <groupId>net.revelc.code</groupId>
-                               <artifactId>impsort-maven-plugin</artifactId>
-                               <executions>
-                                       <execution>
-                                               <id>sort-imports</id>
-                                               <goals>
-                                                       <goal>sort</goal>
-                                               </goals>
-                                               <phase>process-sources</phase>
-                                       </execution>
-                               </executions>
-                       </plugin>
-               </plugins>
-       </build>
-
-       <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>
-                                                               <configuration>
-                                                                       
<systemPropertyVariables>
-                                                                               
<quarkus.package.type>${r"${quarkus.package.type}"}</quarkus.package.type>
-                                                                       
</systemPropertyVariables>
-                                                               </configuration>
-                                                       </execution>
-                                               </executions>
-                                       </plugin>
-                               </plugins>
-                       </build>
-               </profile>
-       </profiles>
-
-</project>
\ No newline at end of file
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/spring-boot-main.tmpl
 
b/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/spring-boot-main.tmpl
new file mode 100644
index 00000000000..a793b4296ca
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/spring-boot-main.tmpl
@@ -0,0 +1,13 @@
+package {{ .PackageName }};
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class {{ .MainClassname }} {
+
+    public static void main(String[] args) {
+        SpringApplication.run({{ .MainClassname }}.class, args);
+    }
+
+}
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/spring-boot-pom.tmpl
 
b/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/spring-boot-pom.tmpl
new file mode 100644
index 00000000000..3ba005dfac6
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/spring-boot-pom.tmpl
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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 
https://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>{{ .SpringBootVersion }}</version>
+        <relativePath/> <!-- lookup parent from repository -->
+    </parent>
+
+    <groupId>{{ .GroupId }}</groupId>
+    <artifactId>{{ .ArtifactId }}</artifactId>
+    <version>{{ .Version }}</version>
+
+    <properties>
+        <java.version>{{ .JavaVersion }}</java.version>
+    </properties>
+
+    <dependencyManagement>
+        <dependencies>
+            <!-- Spring Boot BOM -->
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-dependencies</artifactId>
+                <version>{{ .SpringBootVersion }}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+            <!-- Camel BOM -->
+            <dependency>
+                <groupId>org.apache.camel.springboot</groupId>
+                <artifactId>camel-spring-boot-bom</artifactId>
+                <version>{{ .CamelVersion }}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.camel.springboot</groupId>
+            <artifactId>camel-spring-boot-engine-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel.springboot</groupId>
+            <artifactId>camel-dsl-modeline-starter</artifactId>
+        </dependency>
+{{ .CamelDependencies }}
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-test-spring-junit5</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/CommandLineDependencyDownloader.java
 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/CommandLineDependencyDownloader.java
index f6f4b82cbce..bb598455bf6 100644
--- 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/CommandLineDependencyDownloader.java
+++ 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/CommandLineDependencyDownloader.java
@@ -70,7 +70,8 @@ public class CommandLineDependencyDownloader extends 
ServiceSupport implements C
 
     private boolean isValidGav(String gav) {
         MavenGav mg = MavenGav.parseGav(camelContext, gav);
-        boolean exists = DownloaderHelper.alreadyOnClasspath(camelContext, 
mg.getArtifactId(), mg.getVersion());
+        boolean exists
+                = DownloaderHelper.alreadyOnClasspath(camelContext, 
mg.getGroupId(), mg.getArtifactId(), mg.getVersion());
         // valid if not already on classpath
         return !exists;
     }
diff --git 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloaderClassResolver.java
 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloaderClassResolver.java
index 2f73a8e00ef..d638fe88fb5 100644
--- 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloaderClassResolver.java
+++ 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloaderClassResolver.java
@@ -42,7 +42,8 @@ final class DependencyDownloaderClassResolver extends 
DefaultClassResolver {
             // okay maybe the class is from a known GAV that we can download 
first and then load the class
             MavenGav gav = knownDependenciesResolver.mavenGavForClass(name);
             if (gav != null) {
-                if (!DownloaderHelper.alreadyOnClasspath(getCamelContext(), 
gav.getArtifactId(), gav.getVersion())) {
+                if (!DownloaderHelper.alreadyOnClasspath(getCamelContext(), 
gav.getGroupId(), gav.getArtifactId(),
+                        gav.getVersion())) {
                     DownloaderHelper.downloadDependency(getCamelContext(), 
gav.getGroupId(), gav.getArtifactId(),
                             gav.getVersion());
                 }
diff --git 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloaderComponentResolver.java
 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloaderComponentResolver.java
index db1ef258690..a4cff33c85b 100644
--- 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloaderComponentResolver.java
+++ 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloaderComponentResolver.java
@@ -54,7 +54,8 @@ final class DependencyDownloaderComponentResolver extends 
DefaultComponentResolv
     @Override
     public Component resolveComponent(String name, CamelContext context) {
         ComponentModel model = catalog.componentModel(name);
-        if (model != null && 
!DownloaderHelper.alreadyOnClasspath(camelContext, model.getArtifactId(), 
model.getVersion())) {
+        if (model != null && 
!DownloaderHelper.alreadyOnClasspath(camelContext, model.getGroupId(), 
model.getArtifactId(),
+                model.getVersion())) {
             DownloaderHelper.downloadDependency(camelContext, 
model.getGroupId(), model.getArtifactId(), model.getVersion());
         }
 
diff --git 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloaderDataFormatResolver.java
 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloaderDataFormatResolver.java
index d520a253390..af118d7579e 100644
--- 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloaderDataFormatResolver.java
+++ 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloaderDataFormatResolver.java
@@ -49,7 +49,8 @@ final class DependencyDownloaderDataFormatResolver extends 
DefaultDataFormatReso
     @Override
     public DataFormat createDataFormat(String name, CamelContext context) {
         DataFormatModel model = catalog.dataFormatModel(name);
-        if (model != null && 
!DownloaderHelper.alreadyOnClasspath(camelContext, model.getArtifactId(), 
model.getVersion())) {
+        if (model != null && 
!DownloaderHelper.alreadyOnClasspath(camelContext, model.getGroupId(), 
model.getArtifactId(),
+                model.getVersion())) {
             DownloaderHelper.downloadDependency(camelContext, 
model.getGroupId(), model.getArtifactId(), model.getVersion());
         }
         return super.createDataFormat(name, context);
diff --git 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloaderKamelet.java
 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloaderKamelet.java
index 8bf283d4d39..caae629d72a 100644
--- 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloaderKamelet.java
+++ 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloaderKamelet.java
@@ -181,7 +181,8 @@ final class DependencyDownloaderKamelet extends 
ServiceSupport implements CamelC
             }
 
             MavenGav mg = MavenGav.parseGav(camelContext, gav);
-            boolean exists = DownloaderHelper.alreadyOnClasspath(camelContext, 
mg.getArtifactId(), mg.getVersion());
+            boolean exists
+                    = DownloaderHelper.alreadyOnClasspath(camelContext, 
mg.getGroupId(), mg.getArtifactId(), mg.getVersion());
             // valid if not already on classpath
             return !exists;
         }
diff --git 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloaderLanguageResolver.java
 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloaderLanguageResolver.java
index 38de22c433f..40975edd412 100644
--- 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloaderLanguageResolver.java
+++ 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloaderLanguageResolver.java
@@ -49,7 +49,8 @@ final class DependencyDownloaderLanguageResolver extends 
DefaultLanguageResolver
     @Override
     public Language resolveLanguage(String name, CamelContext context) {
         LanguageModel model = catalog.languageModel(name);
-        if (model != null && 
!DownloaderHelper.alreadyOnClasspath(camelContext, model.getArtifactId(), 
model.getVersion())) {
+        if (model != null && 
!DownloaderHelper.alreadyOnClasspath(camelContext, model.getGroupId(), 
model.getArtifactId(),
+                model.getVersion())) {
             DownloaderHelper.downloadDependency(camelContext, 
model.getGroupId(), model.getArtifactId(), model.getVersion());
         }
 
diff --git 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloaderPropertyBindingListener.java
 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloaderPropertyBindingListener.java
index 974b85a1ea9..4054071bd00 100644
--- 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloaderPropertyBindingListener.java
+++ 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloaderPropertyBindingListener.java
@@ -36,7 +36,8 @@ class DependencyDownloaderPropertyBindingListener implements 
PropertyBindingList
             String s = (String) value;
             MavenGav gav = knownDependenciesResolver.mavenGavForClass(s);
             if (gav != null) {
-                if (!DownloaderHelper.alreadyOnClasspath(camelContext, 
gav.getArtifactId(), gav.getVersion())) {
+                if (!DownloaderHelper.alreadyOnClasspath(camelContext, 
gav.getGroupId(), gav.getArtifactId(),
+                        gav.getVersion())) {
                     DownloaderHelper.downloadDependency(camelContext, 
gav.getGroupId(), gav.getArtifactId(),
                             gav.getVersion());
                 }
diff --git 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloaderRoutesLoader.java
 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloaderRoutesLoader.java
index 6b62fed3a9b..d45fcdb93a2 100644
--- 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloaderRoutesLoader.java
+++ 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloaderRoutesLoader.java
@@ -75,7 +75,8 @@ public class DependencyDownloaderRoutesLoader extends 
MainRoutesLoader {
     }
 
     private void downloadLoader(String artifactId) {
-        if (!DownloaderHelper.alreadyOnClasspath(getCamelContext(), 
artifactId, getCamelContext().getVersion())) {
+        if (!DownloaderHelper.alreadyOnClasspath(getCamelContext(), 
"org.apache.camel", artifactId,
+                getCamelContext().getVersion())) {
             DownloaderHelper.downloadDependency(getCamelContext(), 
"org.apache.camel", artifactId,
                     getCamelContext().getVersion());
         }
diff --git 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloaderStrategy.java
 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloaderStrategy.java
index 44fc10f59ff..6287fb78577 100644
--- 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloaderStrategy.java
+++ 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloaderStrategy.java
@@ -30,7 +30,7 @@ class DependencyDownloaderStrategy implements 
DependencyStrategy {
     @Override
     public void onDependency(String dependency) {
         MavenGav gav = MavenGav.parseGav(camelContext, dependency);
-        if (!DownloaderHelper.alreadyOnClasspath(camelContext, 
gav.getArtifactId(), gav.getVersion())) {
+        if (!DownloaderHelper.alreadyOnClasspath(camelContext, 
gav.getGroupId(), gav.getArtifactId(), gav.getVersion())) {
             DownloaderHelper.downloadDependency(camelContext, 
gav.getGroupId(), gav.getArtifactId(),
                     gav.getVersion());
         }
diff --git 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DownloadListener.java
 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DownloadListener.java
index f0281710677..78c60967738 100644
--- 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DownloadListener.java
+++ 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DownloadListener.java
@@ -21,6 +21,14 @@ package org.apache.camel.main;
  */
 public interface DownloadListener {
 
+    /**
+     * Downloads a new dependency
+     */
     void onDownloadDependency(String groupId, String artifactId, String 
version);
 
+    /**
+     * Uses an existing already downloaded dependency
+     */
+    void onAlreadyDownloadedDependency(String groupId, String artifactId, 
String version);
+
 }
diff --git 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DownloaderHelper.java
 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DownloaderHelper.java
index 8db2dea2938..62ef40adeb6 100644
--- 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DownloaderHelper.java
+++ 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DownloaderHelper.java
@@ -76,7 +76,7 @@ public final class DownloaderHelper {
         }, gav);
     }
 
-    public static boolean alreadyOnClasspath(CamelContext camelContext, String 
artifactId, String version) {
+    public static boolean alreadyOnClasspath(CamelContext camelContext, String 
groupId, String artifactId, String version) {
         // if no artifact then regard this as okay
         if (artifactId == null) {
             return true;
@@ -94,6 +94,11 @@ public final class DownloaderHelper {
                 for (URL u : ucl.getURLs()) {
                     String s = u.toString();
                     if (s.contains(target)) {
+                        // trigger listener
+                        DownloadListener listener = 
camelContext.getExtension(DownloadListener.class);
+                        if (listener != null) {
+                            listener.onAlreadyDownloadedDependency(groupId, 
artifactId, version);
+                        }
                         // already on classpath
                         return true;
                     }

Reply via email to