From 83a0e46472c260504874235f8fc6c98cf716a5a5 Mon Sep 17 00:00:00 2001 From: Pasquale Congiusti Date: Wed, 17 Jun 2026 10:43:14 +0200 Subject: [PATCH] feat(dsl): camel jbang export jib Added a Jib profile to enable the publishing of the container via Jib profile Closes CAMEL-23780 --- .../camel-jbang-configuration-metadata.json | 2 +- .../ROOT/pages/camel-jbang-configuration.adoc | 2 +- .../camel-jbang-configuration-metadata.json | 2 +- .../core/commands/ExportBaseCommand.java | 2 +- .../jbang/core/commands/ExportCamelMain.java | 2 +- .../jbang/core/commands/ExportQuarkus.java | 1 + .../jbang/core/commands/ExportSpringBoot.java | 1 + .../core/common/CamelJBangConstants.java | 4 +- .../src/main/resources/templates/main-pom.ftl | 43 ++++++++++ .../main/resources/templates/quarkus-pom.ftl | 84 +++++++++++++++++++ .../main/resources/templates/readme.md.ftl | 19 +++++ .../resources/templates/readme.native.md.ftl | 37 ++++++++ .../resources/templates/spring-boot-pom.ftl | 43 ++++++++++ .../dsl/jbang/core/commands/ExportTest.java | 16 ++++ .../jbang/core/common/TemplateHelperTest.java | 7 +- 15 files changed, 256 insertions(+), 9 deletions(-) diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/jbang/camel-jbang-configuration-metadata.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/jbang/camel-jbang-configuration-metadata.json index 1265cb95a657d..822581e209438 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/jbang/camel-jbang-configuration-metadata.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/jbang/camel-jbang-configuration-metadata.json @@ -23,7 +23,7 @@ { "name": "camel.jbang.javaVersion", "required": false, "description": "Java version", "type": "enum", "javaType": "String", "defaultValue": "21", "secret": false, "enum": [ "21" ] }, { "name": "camel.jbang.jfr", "required": false, "description": "Enables Java Flight Recorder saving recording to disk on exit", "type": "boolean", "javaType": "boolean", "defaultValue": false, "secret": false }, { "name": "camel.jbang.jfr-profile", "required": false, "description": "Java Flight Recorder profile to use (such as default or profile)", "type": "string", "javaType": "String", "defaultValue": "default", "secret": false }, - { "name": "camel.jbang.jib-maven-plugin-version", "required": false, "description": "Version to use for jib-maven-plugin if exporting to camel-main and have Kubernetes enabled (jkube.xxx options)", "label": "kubernetes", "type": "string", "javaType": "String", "defaultValue": "3.4.5", "secret": false }, + { "name": "camel.jbang.jib-maven-plugin-version", "required": false, "description": "Version to use for jib-maven-plugin when exporting the application", "label": "maven", "type": "string", "javaType": "String", "defaultValue": "3.5.1", "secret": false }, { "name": "camel.jbang.jkube-maven-plugin-version", "required": false, "description": "Version to use for jkube-maven-plugin if exporting to camel-main and have Kubernetes enabled (jkube.xxx options)", "label": "kubernetes", "type": "string", "javaType": "String", "defaultValue": "1.19.0", "secret": false }, { "name": "camel.jbang.jkubeFiles", "required": false, "description": "Resource YAML fragments for Kubernetes using Eclipse JKube tool (Use commas to separate multiple files).", "label": "kubernetes", "type": "string", "javaType": "String", "secret": false }, { "name": "camel.jbang.kameletsVersion", "required": false, "description": "Apache Camel Kamelets version. By default the Kamelets are the same version as Camel.", "type": "string", "javaType": "String", "secret": false }, diff --git a/docs/user-manual/modules/ROOT/pages/camel-jbang-configuration.adoc b/docs/user-manual/modules/ROOT/pages/camel-jbang-configuration.adoc index ac0d930b6f26c..286e856eed951 100644 --- a/docs/user-manual/modules/ROOT/pages/camel-jbang-configuration.adoc +++ b/docs/user-manual/modules/ROOT/pages/camel-jbang-configuration.adoc @@ -29,7 +29,7 @@ The camel.jbang supports 48 options, which are listed below. | *camel.jbang.javaVersion* | Java version | 21 | String | *camel.jbang.jfr* | Enables Java Flight Recorder saving recording to disk on exit | false | boolean | *camel.jbang.jfr-profile* | Java Flight Recorder profile to use (such as default or profile) | default | String -| *camel.jbang.jib-maven-plugin-version* | Version to use for jib-maven-plugin if exporting to camel-main and have Kubernetes enabled (jkube.xxx options) | 3.4.5 | String +| *camel.jbang.jib-maven-plugin-version* | Version to use for jib-maven-plugin when exporting the application | 3.5.1 | String | *camel.jbang.jkube-maven-plugin-version* | Version to use for jkube-maven-plugin if exporting to camel-main and have Kubernetes enabled (jkube.xxx options) | 1.19.0 | String | *camel.jbang.jkubeFiles* | Resource YAML fragments for Kubernetes using Eclipse JKube tool (Use commas to separate multiple files). | | String | *camel.jbang.kameletsVersion* | Apache Camel Kamelets version. By default the Kamelets are the same version as Camel. | | String diff --git a/dsl/camel-jbang/camel-jbang-core/src/generated/resources/META-INF/camel-jbang-configuration-metadata.json b/dsl/camel-jbang/camel-jbang-core/src/generated/resources/META-INF/camel-jbang-configuration-metadata.json index 1265cb95a657d..822581e209438 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/generated/resources/META-INF/camel-jbang-configuration-metadata.json +++ b/dsl/camel-jbang/camel-jbang-core/src/generated/resources/META-INF/camel-jbang-configuration-metadata.json @@ -23,7 +23,7 @@ { "name": "camel.jbang.javaVersion", "required": false, "description": "Java version", "type": "enum", "javaType": "String", "defaultValue": "21", "secret": false, "enum": [ "21" ] }, { "name": "camel.jbang.jfr", "required": false, "description": "Enables Java Flight Recorder saving recording to disk on exit", "type": "boolean", "javaType": "boolean", "defaultValue": false, "secret": false }, { "name": "camel.jbang.jfr-profile", "required": false, "description": "Java Flight Recorder profile to use (such as default or profile)", "type": "string", "javaType": "String", "defaultValue": "default", "secret": false }, - { "name": "camel.jbang.jib-maven-plugin-version", "required": false, "description": "Version to use for jib-maven-plugin if exporting to camel-main and have Kubernetes enabled (jkube.xxx options)", "label": "kubernetes", "type": "string", "javaType": "String", "defaultValue": "3.4.5", "secret": false }, + { "name": "camel.jbang.jib-maven-plugin-version", "required": false, "description": "Version to use for jib-maven-plugin when exporting the application", "label": "maven", "type": "string", "javaType": "String", "defaultValue": "3.5.1", "secret": false }, { "name": "camel.jbang.jkube-maven-plugin-version", "required": false, "description": "Version to use for jkube-maven-plugin if exporting to camel-main and have Kubernetes enabled (jkube.xxx options)", "label": "kubernetes", "type": "string", "javaType": "String", "defaultValue": "1.19.0", "secret": false }, { "name": "camel.jbang.jkubeFiles", "required": false, "description": "Resource YAML fragments for Kubernetes using Eclipse JKube tool (Use commas to separate multiple files).", "label": "kubernetes", "type": "string", "javaType": "String", "secret": false }, { "name": "camel.jbang.kameletsVersion", "required": false, "description": "Apache Camel Kamelets version. By default the Kamelets are the same version as Camel.", "type": "string", "javaType": "String", "secret": false }, diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportBaseCommand.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportBaseCommand.java index e0c07c2f1a79b..d6bf27e829e19 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportBaseCommand.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportBaseCommand.java @@ -1213,7 +1213,7 @@ protected static String jibMavenPluginVersion(Path settings, Properties prop) { // ignore } } - return answer != null ? answer : "3.4.5"; + return answer != null ? answer : "3.5.1"; } protected static String jkubeMavenPluginVersion(Path settings, Properties props) { diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportCamelMain.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportCamelMain.java index d5539a39e7634..b6f479b1653f8 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportCamelMain.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportCamelMain.java @@ -214,6 +214,7 @@ private void createMavenPom(Path settings, Path profile, Path pom, Set d model.put("BuildProperties", formatBuildProperties()); model.put("Repositories", buildRepositoryList(repos)); model.put("Dependencies", buildDependencyList(deps)); + model.put("JibMavenPluginVersion", jibMavenPluginVersion(settings, prop)); // kubernetes/docker properties enrichKubernetesModel(model, settings, profile); @@ -254,7 +255,6 @@ private void enrichKubernetesModel(Map model, Path settings, Pat model.put("hasJib", jib || jkube); model.put("hasJkube", jkube); if (jib || jkube) { - model.put("JibMavenPluginVersion", jibMavenPluginVersion(settings, prop)); model.put("hasJibFromAuth", prop.stringPropertyNames().stream().anyMatch(s -> s.startsWith("jib.from.auth."))); model.put("hasJibToAuth", diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportQuarkus.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportQuarkus.java index 1d002e0caae71..6f435d65a1f5b 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportQuarkus.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportQuarkus.java @@ -392,6 +392,7 @@ private void createMavenPom(Path settings, Path pom, Set deps) throws Ex model.put("BuildProperties", formatBuildProperties()); model.put("Repositories", buildRepositoryList(repos)); model.put("Dependencies", depList); + model.put("JibMavenPluginVersion", jibMavenPluginVersion(settings, prop)); String context = TemplateHelper.processTemplate(pomTemplateName, model); Files.writeString(pom, context); 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 index f991c786b34a4..4f3433d31a83c 100644 --- 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 @@ -225,6 +225,7 @@ private void createMavenPom(Path settings, Path profile, Path pom, Set d model.put("BuildProperties", formatBuildProperties()); model.put("Repositories", buildRepositoryList(repos)); model.put("Dependencies", depList); + model.put("JibMavenPluginVersion", jibMavenPluginVersion(settings, prop)); String context = TemplateHelper.processTemplate(pomTemplateName, model); IOHelper.writeText(context, Files.newOutputStream(pom)); diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/CamelJBangConstants.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/CamelJBangConstants.java index 6bdbc5d2221f6..de13ed94b4f40 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/CamelJBangConstants.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/CamelJBangConstants.java @@ -147,8 +147,8 @@ public final class CamelJBangConstants { @Metadata(description = "Additional dependencies for Quarkus runtime only", javaType = "String") public static final String DEPENDENCIES_QUARKUS = "camel.jbang.dependencies.quarkus"; - @Metadata(description = "Version to use for jib-maven-plugin if exporting to camel-main and have Kubernetes enabled (jkube.xxx options)", - javaType = "String", defaultValue = "3.4.5", label = "kubernetes") + @Metadata(description = "Version to use for jib-maven-plugin when exporting the application", + javaType = "String", defaultValue = "3.5.1", label = "maven") public static final String JIB_MAVEN_PLUGIN_VERSION = "camel.jbang.jib-maven-plugin-version"; @Metadata(description = "Version to use for jkube-maven-plugin if exporting to camel-main and have Kubernetes enabled (jkube.xxx options)", diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/main-pom.ftl b/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/main-pom.ftl index 5d379994932e5..a5bf0a3966ec4 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/main-pom.ftl +++ b/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/main-pom.ftl @@ -299,6 +299,49 @@ + + + jib + + false + + + + + com.google.cloud.tools + jib-maven-plugin + [=JibMavenPluginVersion] + + true + + + + ${project.build.directory} + /deployments + + ${project.build.finalName}.jar + + + + + + /deployments/${project.build.finalName}.jar + 644 + + + + + + java + -jar + /deployments/${project.build.finalName}.jar + + + + + + + diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/quarkus-pom.ftl b/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/quarkus-pom.ftl index 7852e5fed0807..2e826b283f295 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/quarkus-pom.ftl +++ b/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/quarkus-pom.ftl @@ -202,6 +202,43 @@ false native + + + + + + com.google.cloud.tools + jib-maven-plugin + [=JibMavenPluginVersion] + + true + + + + ${project.build.directory} + /deployments + + ${project.build.finalName}-runner + + + + + + /deployments/${project.build.finalName}-runner + 755 + + + + + + /deployments/${project.build.finalName}-runner + + + + + + + camel.debug @@ -256,6 +293,53 @@ + + + + jib + + false + + + uber-jar + + + + + com.google.cloud.tools + jib-maven-plugin + [=JibMavenPluginVersion] + + true + + + + ${project.build.directory} + /deployments + + ${project.build.finalName}-runner.jar + + + + + + /deployments/${project.build.finalName}-runner.jar + 644 + + + + + + java + -jar + /deployments/${project.build.finalName}-runner.jar + + + + + + + diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/readme.md.ftl b/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/readme.md.ftl index ccbbf837add8b..b77a90cc46c13 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/readme.md.ftl +++ b/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/readme.md.ftl @@ -55,3 +55,22 @@ Once the application is published, you can run it directly from the container: ```bash docker run -it [=ArtifactId]:[=Version] ``` + +## Create a container with Jib plugin + +If you don't want to deal with Docker resources, you can use the `jib` profile. This tool works inside Maven and is in charge to build and push a container +out of the box. The profile is configured to produce an executable jar (regardless of the runtime chosen). You can provide any argument expected by the plugin: + +```bash +mvn clean package jib:build -Pjib \ + -Djib.to.image=my-registry.io/my-registry-org/my-container:latest \ + -Djib.from.image=eclipse-temurin:21-jdk \ + -Djib.container.user=1000 +``` + +You can use any base image with a compatible JVM which provides a `java` executable in the path. Once the application is published, +you can run it directly from the container: + +```bash +docker run my-registry.io/my-registry-org/my-container:latest +``` diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/readme.native.md.ftl b/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/readme.native.md.ftl index 3d6bf2345661c..c2880e7440ae8 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/readme.native.md.ftl +++ b/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/readme.native.md.ftl @@ -56,6 +56,25 @@ Once the application is published, you can run it directly from the container: docker run -it [=ArtifactId]:[=Version] ``` +## Create a container with Jib plugin (JVM mode) + +If you don't want to deal with Docker resources, you can use the `jib` profile. This tool works inside Maven and is in charge to build and push a container +out of the box. The profile is configured to produce an executable jar (regardless of the runtime chosen). You can provide any argument expected by the plugin: + +```bash +mvn clean package jib:build -Pjib \ + -Djib.to.image=my-registry.io/my-registry-org/my-container:latest \ + -Djib.from.image=eclipse-temurin:21-jdk \ + -Djib.container.user=1000 +``` + +You can use any base image with a compatible JVM which provides a `java` executable in the path. Once the application is published, +you can run it directly from the container: + +```bash +docker run my-registry.io/my-registry-org/my-container:latest +``` + ## Build the Maven project (Native mode) ```bash @@ -81,3 +100,21 @@ Once the application is published, you can run it directly from the container: ```bash docker run -it native-[=ArtifactId]:[=Version] ``` + +## Create a container with Jib plugin (Native mode) + +If you don't want to deal with Docker resources, you can use the `jib` profile. This tool works inside Maven and is in charge to build and push a container +out of the box. The profile is configured to produce a native executable. You can provide any argument expected by the plugin: + +```bash +mvn clean package jib:build -Pnative \ + -Djib.to.image=my-registry.io/my-registry-org/my-container:latest \ + -Djib.from.image=eclipse-temurin:21-jdk \ + -Djib.container.user=1000 +``` + +You can use any base image (even non JVM one) as the Quarkus native is an executable. Once the application is published, you can run it directly from the container: + +```bash +docker run my-registry.io/my-registry-org/my-container:latest +``` diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/spring-boot-pom.ftl b/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/spring-boot-pom.ftl index 5cdda39a50605..839893fd627c6 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/spring-boot-pom.ftl +++ b/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/spring-boot-pom.ftl @@ -202,6 +202,49 @@ + + + jib + + false + + + + + com.google.cloud.tools + jib-maven-plugin + [=JibMavenPluginVersion] + + true + + + + ${project.build.directory} + /deployments + + ${project.build.finalName}.jar + + + + + + /deployments/${project.build.finalName}.jar + 644 + + + + + + java + -jar + /deployments/${project.build.finalName}.jar + + + + + + + diff --git a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ExportTest.java b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ExportTest.java index 855bb1222ddae..8ea1f21fe19ac 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ExportTest.java +++ b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ExportTest.java @@ -914,4 +914,20 @@ public void shouldExportHawtio(RuntimeType rt) throws Exception { } } + @ParameterizedTest + @MethodSource("runtimeProvider") + public void shouldContainJibProfile(RuntimeType rt) throws Exception { + Export command = new Export(new CamelJBangMain()); + CommandLine.populateCommand(command, "--gav=examples:route:1.0.0", "--dir=" + workingDir, + "--runtime=%s".formatted(rt.runtime()), "src/test/resources/route.yaml"); + int exit = command.doCall(); + + Assertions.assertEquals(0, exit); + + File f = new File(workingDir, "pom.xml"); + String content = IOHelper.loadText(new FileInputStream(f)); + Assertions.assertTrue(content.contains("jib"), + "Jib profile not exported!"); + } + } diff --git a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/common/TemplateHelperTest.java b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/common/TemplateHelperTest.java index 5a8ce163655d6..dd2e5867ca22e 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/common/TemplateHelperTest.java +++ b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/common/TemplateHelperTest.java @@ -210,6 +210,7 @@ void testMainPomTemplateWithDependencies() throws IOException { model.put("KubernetesProperties", List.of()); model.put("hasJib", false); model.put("hasJkube", false); + model.put("JibMavenPluginVersion", "3.5.1"); List> deps = new ArrayList<>(); Map dep = new HashMap<>(); @@ -240,8 +241,7 @@ void testMainPomTemplateWithDependencies() throws IOException { // lib dependency should use system scope with ${project.basedir} assertTrue(result.contains("${project.basedir}"), "Lib dep should have project.basedir system path"); assertTrue(result.contains("system")); - // No jib/jkube plugins - assertFalse(result.contains("jib-maven-plugin")); + // No jkube plugins assertFalse(result.contains("kubernetes-maven-plugin")); } @@ -260,6 +260,7 @@ void testMainPomTemplateWithRepositories() throws IOException { model.put("hasJib", false); model.put("hasJkube", false); model.put("Dependencies", List.of()); + model.put("JibMavenPluginVersion", "3.5.1"); List> repos = new ArrayList<>(); repos.add(Map.of("id", "custom1", "url", "https://repo.example.com/snapshots", "isSnapshot", true)); @@ -286,6 +287,7 @@ void testSpringBootPomTemplate() throws IOException { model.put("BuildProperties", ""); model.put("Repositories", List.of()); model.put("Dependencies", List.of()); + model.put("JibMavenPluginVersion", "3.5.1"); String result = TemplateHelper.processTemplate("spring-boot-pom.ftl", model); @@ -311,6 +313,7 @@ void testQuarkusPomTemplate() throws IOException { model.put("BuildProperties", ""); model.put("Repositories", List.of()); model.put("Dependencies", List.of()); + model.put("JibMavenPluginVersion", "3.5.1"); String result = TemplateHelper.processTemplate("quarkus-pom.ftl", model);