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

davsclaus pushed a commit to branch fix/CAMEL-24661-console
in repository https://gitbox.apache.org/repos/asf/camel.git

commit fc34ab32071443af0c0f50a9563d44a9a040f075
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu Sep 17 10:13:56 2026 +0200

    CAMEL-24661: camel-jbang - --console with the Spring Boot and Quarkus 
runtimes
    
    camel run --console and camel export --console only enabled the developer
    console with Camel Main. The Spring Boot export now adds
    camel-console-starter (the camel actuator endpoint at /actuator/camel)
    and exposes it, keeping health and prometheus exposed when --observe is
    also used (the console is then at /observe/camel on the management
    port). The Quarkus export adds the camel-quarkus-console extension
    (/q/camel/dev-console) and sets exposure-mode=ALL as camel run without
    --dev runs via quarkus:run in prod mode. The console is enabled with the
    shared camel.main.devConsoleEnabled option on all runtimes.
    
    camel run --runtime=quarkus|spring-boot also did not pass --observe and
    --console on to the exporter at all; only the Camel Main run did.
    
    Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../modules/ROOT/pages/camel-jbang-managing.adoc   |  7 ++
 .../modules/ROOT/pages/camel-jbang-running.adoc    |  8 +-
 .../pages/jbang-commands/camel-jbang-debug.adoc    |  2 +-
 .../camel-jbang-dependency-copy.adoc               |  2 +-
 .../camel-jbang-dependency-list.adoc               |  2 +-
 .../camel-jbang-dependency-update.adoc             |  2 +-
 .../ROOT/pages/jbang-commands/camel-jbang-dev.adoc |  2 +-
 .../pages/jbang-commands/camel-jbang-export.adoc   |  2 +-
 .../ROOT/pages/jbang-commands/camel-jbang-run.adoc |  2 +-
 .../pages/jbang-commands/camel-jbang-sbom.adoc     |  2 +-
 .../META-INF/camel-jbang-commands-metadata.json    | 12 +--
 .../dsl/jbang/core/commands/ExportBaseCommand.java |  3 +-
 .../dsl/jbang/core/commands/ExportQuarkus.java     | 18 +++++
 .../dsl/jbang/core/commands/ExportSpringBoot.java  | 41 ++++++++--
 .../apache/camel/dsl/jbang/core/commands/Run.java  |  8 +-
 .../camel/dsl/jbang/core/commands/ExportTest.java  | 94 ++++++++++++++++++----
 16 files changed, 165 insertions(+), 42 deletions(-)

diff --git a/docs/user-manual/modules/ROOT/pages/camel-jbang-managing.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-jbang-managing.adoc
index 6e55603866cf..2f3c5b94536b 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-jbang-managing.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-jbang-managing.adoc
@@ -288,6 +288,13 @@ camel run hello.java --console
 The console is accessible at http://localhost:8080/q/dev and provides insights 
into routes,
 performance, and EIP-level metrics. The endpoints support both HTTP GET and 
POST.
 
+When running with xref:camel-jbang-running.adoc#_runtimes[another runtime], 
the console is served where
+that runtime puts it: `/q/dev` with Camel Main, `/actuator/camel` with Spring 
Boot (the `camel` actuator
+endpoint; with `--observe` it moves to the management port under 
`/observe/camel`), and
+`/q/camel/dev-console` with Quarkus. The exported Quarkus project exposes the 
console in prod mode
+(`quarkus.camel.console.exposure-mode=ALL`) as `camel run` without `--dev` 
runs via `quarkus:run`. The
+console has no authentication on any runtime, so it is meant for local 
development only.
+
 GET with query parameters:
 
 [source,bash]
diff --git a/docs/user-manual/modules/ROOT/pages/camel-jbang-running.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-jbang-running.adoc
index ea0b9443b16b..a835b0948e79 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-jbang-running.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-jbang-running.adoc
@@ -259,7 +259,9 @@ This is the same JVM you would get from `camel export`, and 
is what the Camel TU
 launching examples and folders.
 
 The options `--profile`, `--port`, `--prop`, `--max-seconds`, 
`--max-messages`, `--max-idle-seconds`,
-`--jvm-args` and `--jfr` are passed to the application on all three runtimes. 
The application logs to a
+`--jvm-args`, `--jfr`, `--observe` and `--console` are passed to the 
application on all three runtimes
+(each runtime serves the developer console on its own path, see
+xref:camel-jbang-managing.adoc#_developer_console[Developer Console]). The 
application logs to a
 file in `~/.camel` so `camel log` and the TUI can read the logs: `<pid>.log` 
for Spring Boot, and
 `<name>.log` for Quarkus and Camel Main (`<name>` is the name the application 
reports, from `--name` or
 else the first route file).
@@ -269,9 +271,7 @@ Limitations compared to the `jbang` runtime:
 - Startup is slower, as the project must be built with Maven first (the first 
run also downloads
   the Maven wrapper and plugins).
 - New components cannot be auto-detected while running (stop and run again to 
update dependencies).
-- `--console` is supported with Camel Main (the exported project enables the 
developer console, health, info
-  and Jolokia), but not yet with Spring Boot and Quarkus. The deprecated 
`--health` and `--metrics` options
-  are not supported in a separate JVM; use `--observe` instead.
+- The deprecated `--health` and `--metrics` options are not supported in a 
separate JVM; use `--observe` instead.
 - Options that only work in-process are not supported: `--background`, 
`--code`, `--open-api`,
   `--empty` and `--mcp-stdio`.
 - Dev mode reloads YAML and XML route files from the original source 
directory; Java sources cannot
diff --git 
a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-debug.adoc 
b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-debug.adoc
index 113de9e29b8e..8b197c2c638a 100644
--- a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-debug.adoc
+++ b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-debug.adoc
@@ -27,7 +27,7 @@ camel debug [options]
 | `--camel-spring-boot-version` | To run using a different Camel Spring Boot 
version than the default version. |  | String
 | `--camel-version` | To run using a different Camel version than the default 
version. |  | String
 | `--code` | Run the given text or file as Java DSL routes |  | String
-| `--console` | Developer console at /q/dev on local HTTP server (port 8080 by 
default) | false | boolean
+| `--console` | Developer console on the local HTTP server (port 8080 by 
default): /q/dev with the jbang and Camel Main runtimes, /actuator/camel with 
Spring Boot, and /q/camel/dev-console with Quarkus | false | boolean
 | `--dep,--dependency` | Add additional dependencies |  | List
 | `--download` | Whether to allow automatic downloading JAR dependencies (over 
the internet) | true | boolean
 | `--empty` | Run an empty Camel without loading source files | false | boolean
diff --git 
a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-dependency-copy.adoc
 
b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-dependency-copy.adoc
index 45262e173d18..5aa33e5b1701 100644
--- 
a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-dependency-copy.adoc
+++ 
b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-dependency-copy.adoc
@@ -24,7 +24,7 @@ camel dependency copy [options]
 | `--camel-version` | To export using a different Camel version than the 
default version. |  | String
 | `--camel-wrapper` | Include Camel Wrapper scripts in exported project for 
version pinning | false | boolean
 | `--clean-dir` | If exporting to current directory (default) then all 
existing files are preserved. Enabling this option will force cleaning current 
directory including all sub dirs (use this with care) | false | boolean
-| `--console` | Developer console at /q/dev on local HTTP server (port 8080 by 
default). Camel Main runtime only. | false | boolean
+| `--console` | Developer console on the local HTTP server (port 8080 by 
default): /q/dev with Camel Main, /actuator/camel with Spring Boot, and 
/q/camel/dev-console with Quarkus | false | boolean
 | `--dep,--dependency` | Add additional dependencies |  | List
 | `--dir,--directory` | Directory where the project will be exported | . | 
String
 | `--docker` | Include Docker files in exported project | true | boolean
diff --git 
a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-dependency-list.adoc
 
b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-dependency-list.adoc
index 2acf69d415cb..5eefd596dfcc 100644
--- 
a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-dependency-list.adoc
+++ 
b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-dependency-list.adoc
@@ -24,7 +24,7 @@ camel dependency list [options]
 | `--camel-version` | To export using a different Camel version than the 
default version. |  | String
 | `--camel-wrapper` | Include Camel Wrapper scripts in exported project for 
version pinning | false | boolean
 | `--clean-dir` | If exporting to current directory (default) then all 
existing files are preserved. Enabling this option will force cleaning current 
directory including all sub dirs (use this with care) | false | boolean
-| `--console` | Developer console at /q/dev on local HTTP server (port 8080 by 
default). Camel Main runtime only. | false | boolean
+| `--console` | Developer console on the local HTTP server (port 8080 by 
default): /q/dev with Camel Main, /actuator/camel with Spring Boot, and 
/q/camel/dev-console with Quarkus | false | boolean
 | `--dep,--dependency` | Add additional dependencies |  | List
 | `--dir,--directory` | Directory where the project will be exported | . | 
String
 | `--docker` | Include Docker files in exported project | true | boolean
diff --git 
a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-dependency-update.adoc
 
b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-dependency-update.adoc
index 4e2e7f9ef4e8..468e917ed9fa 100644
--- 
a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-dependency-update.adoc
+++ 
b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-dependency-update.adoc
@@ -25,7 +25,7 @@ camel dependency update [options]
 | `--camel-wrapper` | Include Camel Wrapper scripts in exported project for 
version pinning | false | boolean
 | `--clean` | Regenerate list of dependencies (do not keep existing 
dependencies). Not supported for pom.xml |  | boolean
 | `--clean-dir` | If exporting to current directory (default) then all 
existing files are preserved. Enabling this option will force cleaning current 
directory including all sub dirs (use this with care) | false | boolean
-| `--console` | Developer console at /q/dev on local HTTP server (port 8080 by 
default). Camel Main runtime only. | false | boolean
+| `--console` | Developer console on the local HTTP server (port 8080 by 
default): /q/dev with Camel Main, /actuator/camel with Spring Boot, and 
/q/camel/dev-console with Quarkus | false | boolean
 | `--dep,--dependency` | Add additional dependencies |  | List
 | `--dir,--directory` | Directory where the project will be exported | . | 
String
 | `--docker` | Include Docker files in exported project | true | boolean
diff --git 
a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-dev.adoc 
b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-dev.adoc
index ad6e0e9c9f05..1a0754b29298 100644
--- a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-dev.adoc
+++ b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-dev.adoc
@@ -25,7 +25,7 @@ camel dev [options]
 | `--camel-spring-boot-version` | To run using a different Camel Spring Boot 
version than the default version. |  | String
 | `--camel-version` | To run using a different Camel version than the default 
version. |  | String
 | `--code` | Run the given text or file as Java DSL routes |  | String
-| `--console` | Developer console at /q/dev on local HTTP server (port 8080 by 
default) | false | boolean
+| `--console` | Developer console on the local HTTP server (port 8080 by 
default): /q/dev with the jbang and Camel Main runtimes, /actuator/camel with 
Spring Boot, and /q/camel/dev-console with Quarkus | false | boolean
 | `--dep,--dependency` | Add additional dependencies |  | List
 | `--download` | Whether to allow automatic downloading JAR dependencies (over 
the internet) | true | boolean
 | `--empty` | Run an empty Camel without loading source files | false | boolean
diff --git 
a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-export.adoc 
b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-export.adoc
index 4d15ca127f87..af05d379d80c 100644
--- a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-export.adoc
+++ b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-export.adoc
@@ -24,7 +24,7 @@ camel export [options]
 | `--camel-version` | To export using a different Camel version than the 
default version. |  | String
 | `--camel-wrapper` | Include Camel Wrapper scripts in exported project for 
version pinning | false | boolean
 | `--clean-dir` | If exporting to current directory (default) then all 
existing files are preserved. Enabling this option will force cleaning current 
directory including all sub dirs (use this with care) | false | boolean
-| `--console` | Developer console at /q/dev on local HTTP server (port 8080 by 
default). Camel Main runtime only. | false | boolean
+| `--console` | Developer console on the local HTTP server (port 8080 by 
default): /q/dev with Camel Main, /actuator/camel with Spring Boot, and 
/q/camel/dev-console with Quarkus | false | boolean
 | `--dep,--dependency` | Add additional dependencies |  | List
 | `--dir,--directory` | Directory where the project will be exported | . | 
String
 | `--docker` | Include Docker files in exported project | true | boolean
diff --git 
a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-run.adoc 
b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-run.adoc
index af231c6a740e..067e0734f8d4 100644
--- a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-run.adoc
+++ b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-run.adoc
@@ -25,7 +25,7 @@ camel run [options]
 | `--camel-spring-boot-version` | To run using a different Camel Spring Boot 
version than the default version. |  | String
 | `--camel-version` | To run using a different Camel version than the default 
version. |  | String
 | `--code` | Run the given text or file as Java DSL routes |  | String
-| `--console` | Developer console at /q/dev on local HTTP server (port 8080 by 
default) | false | boolean
+| `--console` | Developer console on the local HTTP server (port 8080 by 
default): /q/dev with the jbang and Camel Main runtimes, /actuator/camel with 
Spring Boot, and /q/camel/dev-console with Quarkus | false | boolean
 | `--dep,--dependency` | Add additional dependencies |  | List
 | `--download` | Whether to allow automatic downloading JAR dependencies (over 
the internet) | true | boolean
 | `--empty` | Run an empty Camel without loading source files | false | boolean
diff --git 
a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-sbom.adoc 
b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-sbom.adoc
index 92f5448a7fb3..13c4d839acfc 100644
--- a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-sbom.adoc
+++ b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-sbom.adoc
@@ -24,7 +24,7 @@ camel sbom [options]
 | `--camel-version` | To export using a different Camel version than the 
default version. |  | String
 | `--camel-wrapper` | Include Camel Wrapper scripts in exported project for 
version pinning | false | boolean
 | `--clean-dir` | If exporting to current directory (default) then all 
existing files are preserved. Enabling this option will force cleaning current 
directory including all sub dirs (use this with care) | false | boolean
-| `--console` | Developer console at /q/dev on local HTTP server (port 8080 by 
default). Camel Main runtime only. | false | boolean
+| `--console` | Developer console on the local HTTP server (port 8080 by 
default): /q/dev with Camel Main, /actuator/camel with Spring Boot, and 
/q/camel/dev-console with Quarkus | false | boolean
 | `--cyclonedx-plugin-version` | The CycloneDX Maven Plugin version | 2.9.1 | 
String
 | `--dep,--dependency` | Add additional dependencies |  | List
 | `--dir,--directory` | Directory where the project will be exported | . | 
String
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/generated/resources/META-INF/camel-jbang-commands-metadata.json
 
b/dsl/camel-jbang/camel-jbang-core/src/generated/resources/META-INF/camel-jbang-commands-metadata.json
index 47fcc4d2f6ae..445903276915 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/generated/resources/META-INF/camel-jbang-commands-metadata.json
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/generated/resources/META-INF/camel-jbang-commands-metadata.json
@@ -6,15 +6,15 @@
     { "name": "cmd", "fullName": "cmd", "description": "Performs commands in 
the running Camel integrations, such as start\/stop route, or change logging 
levels.", "sourceClass": 
"org.apache.camel.dsl.jbang.core.commands.action.CamelAction", "options": [ { 
"names": "-h,--help", "description": "Display the help and sub-commands", 
"javaType": "boolean", "type": "boolean" } ], "subcommands": [ { "name": 
"browse", "fullName": "cmd browse", "description": "Browse pending messages on 
endpoints [...]
     { "name": "completion", "fullName": "completion", "description": "Generate 
completion script for bash\/zsh", "sourceClass": 
"org.apache.camel.dsl.jbang.core.commands.Complete", "options": [ { "names": 
"-h,--help", "description": "Display the help and sub-commands", "javaType": 
"boolean", "type": "boolean" } ] },
     { "name": "config", "fullName": "config", "description": "Get and set user 
configuration values", "sourceClass": 
"org.apache.camel.dsl.jbang.core.commands.config.ConfigCommand", "options": [ { 
"names": "-h,--help", "description": "Display the help and sub-commands", 
"javaType": "boolean", "type": "boolean" } ], "subcommands": [ { "name": "get", 
"fullName": "config get", "description": "Display user configuration value", 
"sourceClass": "org.apache.camel.dsl.jbang.core.commands.config. [...]
-    { "name": "debug", "fullName": "debug", "description": "Debug local Camel 
integration", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.Debug", 
"options": [ { "names": "--ago", "description": "Use ago instead of yyyy-MM-dd 
HH:mm:ss in timestamp.", "javaType": "boolean", "type": "boolean" }, { "names": 
"--background", "description": "Run in the background", "defaultValue": 
"false", "javaType": "boolean", "type": "boolean" }, { "names": 
"--background-wait", "description": "To  [...]
-    { "name": "dependency", "fullName": "dependency", "description": "Displays 
all Camel dependencies required to run", "sourceClass": 
"org.apache.camel.dsl.jbang.core.commands.DependencyCommand", "options": [ { 
"names": "-h,--help", "description": "Display the help and sub-commands", 
"javaType": "boolean", "type": "boolean" } ], "subcommands": [ { "name": 
"copy", "fullName": "dependency copy", "description": "Copies all Camel 
dependencies required to run to a specific directory", "sourc [...]
-    { "name": "dev", "fullName": "dev", "description": "Run in dev mode with 
live reload", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.Dev", 
"options": [ { "names": "--background", "description": "Run in the background", 
"defaultValue": "false", "javaType": "boolean", "type": "boolean" }, { "names": 
"--background-wait", "description": "To wait for run in background to startup 
successfully, before returning", "defaultValue": "true", "javaType": "boolean", 
"type": "boolean" }, [...]
+    { "name": "debug", "fullName": "debug", "description": "Debug local Camel 
integration", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.Debug", 
"options": [ { "names": "--ago", "description": "Use ago instead of yyyy-MM-dd 
HH:mm:ss in timestamp.", "javaType": "boolean", "type": "boolean" }, { "names": 
"--background", "description": "Run in the background", "defaultValue": 
"false", "javaType": "boolean", "type": "boolean" }, { "names": 
"--background-wait", "description": "To  [...]
+    { "name": "dependency", "fullName": "dependency", "description": "Displays 
all Camel dependencies required to run", "sourceClass": 
"org.apache.camel.dsl.jbang.core.commands.DependencyCommand", "options": [ { 
"names": "-h,--help", "description": "Display the help and sub-commands", 
"javaType": "boolean", "type": "boolean" } ], "subcommands": [ { "name": 
"copy", "fullName": "dependency copy", "description": "Copies all Camel 
dependencies required to run to a specific directory", "sourc [...]
+    { "name": "dev", "fullName": "dev", "description": "Run in dev mode with 
live reload", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.Dev", 
"options": [ { "names": "--background", "description": "Run in the background", 
"defaultValue": "false", "javaType": "boolean", "type": "boolean" }, { "names": 
"--background-wait", "description": "To wait for run in background to startup 
successfully, before returning", "defaultValue": "true", "javaType": "boolean", 
"type": "boolean" }, [...]
     { "name": "dirty", "fullName": "dirty", "description": "Check if there are 
dirty files from previous Camel runs that did not terminate gracefully", 
"sourceClass": "org.apache.camel.dsl.jbang.core.commands.process.Dirty", 
"options": [ { "names": "--clean", "description": "Clean dirty files which are 
no longer in use", "defaultValue": "false", "javaType": "boolean", "type": 
"boolean" }, { "names": "-h,--help", "description": "Display the help and 
sub-commands", "javaType": "boolean", " [...]
     { "name": "doc", "fullName": "doc", "description": "Shows documentation 
for kamelet, component, and other Camel resources", "sourceClass": 
"org.apache.camel.dsl.jbang.core.commands.catalog.CatalogDoc", "options": [ { 
"names": "--camel-version", "description": "To use a different Camel version 
than the default version", "javaType": "java.lang.String", "type": "string" }, 
{ "names": "--download", "description": "Whether to allow automatic downloading 
JAR dependencies (over the internet [...]
     { "name": "doctor", "fullName": "doctor", "description": "Checks the 
environment and reports potential issues", "sourceClass": 
"org.apache.camel.dsl.jbang.core.commands.Doctor", "options": [ { "names": 
"-h,--help", "description": "Display the help and sub-commands", "javaType": 
"boolean", "type": "boolean" } ] },
     { "name": "eval", "fullName": "eval", "description": "Evaluate Camel 
expressions and scripts", "sourceClass": 
"org.apache.camel.dsl.jbang.core.commands.EvalCommand", "options": [ { "names": 
"-h,--help", "description": "Display the help and sub-commands", "javaType": 
"boolean", "type": "boolean" } ], "subcommands": [ { "name": "expression", 
"fullName": "eval expression", "description": "Evaluates Camel expression", 
"sourceClass": "org.apache.camel.dsl.jbang.core.commands.action.EvalEx [...]
     { "name": "explain", "fullName": "explain", "description": "Explain what a 
Camel route does using AI\/LLM", "sourceClass": 
"org.apache.camel.dsl.jbang.core.commands.Explain", "options": [ { "names": 
"--api-key", "description": "API key for authentication. Also reads 
ANTHROPIC_API_KEY, OPENAI_API_KEY, WATSONX_APIKEY, or LLM_API_KEY env vars", 
"javaType": "java.lang.String", "type": "string" }, { "names": "--api-type", 
"description": "API type: 'ollama', 'openai' (OpenAI-compatible), ' [...]
-    { "name": "export", "fullName": "export", "description": "Export to other 
runtimes (Camel Main, Spring Boot, or Quarkus)", "sourceClass": 
"org.apache.camel.dsl.jbang.core.commands.Export", "options": [ { "names": 
"--build-property", "description": "Maven build properties, ex. 
--build-property=prop1=foo", "javaType": "java.util.List", "type": "array" }, { 
"names": "--camel-spring-boot-version", "description": "Camel version to use 
with Spring Boot", "javaType": "java.lang.String", "ty [...]
+    { "name": "export", "fullName": "export", "description": "Export to other 
runtimes (Camel Main, Spring Boot, or Quarkus)", "sourceClass": 
"org.apache.camel.dsl.jbang.core.commands.Export", "options": [ { "names": 
"--build-property", "description": "Maven build properties, ex. 
--build-property=prop1=foo", "javaType": "java.util.List", "type": "array" }, { 
"names": "--camel-spring-boot-version", "description": "Camel version to use 
with Spring Boot", "javaType": "java.lang.String", "ty [...]
     { "name": "get", "fullName": "get", "description": "Get status of Camel 
integrations", "sourceClass": 
"org.apache.camel.dsl.jbang.core.commands.process.CamelStatus", "options": [ { 
"names": "--watch", "description": "Execute periodically and showing output 
fullscreen", "javaType": "boolean", "type": "boolean" }, { "names": 
"-h,--help", "description": "Display the help and sub-commands", "javaType": 
"boolean", "type": "boolean" } ], "subcommands": [ { "name": "activity", 
"fullName": " [...]
     { "name": "harden", "fullName": "harden", "description": "Suggest security 
hardening for Camel routes using AI\/LLM", "sourceClass": 
"org.apache.camel.dsl.jbang.core.commands.Harden", "options": [ { "names": 
"--api-key", "description": "API key for authentication. Also reads 
OPENAI_API_KEY or LLM_API_KEY env vars", "javaType": "java.lang.String", 
"type": "string" }, { "names": "--api-type", "description": "API type: 'ollama' 
or 'openai' (OpenAI-compatible)", "defaultValue": "ollama", [...]
     { "name": "hawtio", "fullName": "hawtio", "description": "Launch Hawtio 
web console", "sourceClass": 
"org.apache.camel.dsl.jbang.core.commands.process.Hawtio", "options": [ { 
"names": "--host", "description": "Hostname to bind the Hawtio web console to", 
"defaultValue": "127.0.0.1", "javaType": "java.lang.String", "type": "string" 
}, { "names": "--openUrl", "description": "To automatic open Hawtio web console 
in the web browser", "defaultValue": "true", "javaType": "boolean", "type": 
[...]
@@ -26,8 +26,8 @@
     { "name": "plugin", "fullName": "plugin", "description": "Manage plugins 
that add sub-commands to this CLI", "sourceClass": 
"org.apache.camel.dsl.jbang.core.commands.plugin.PluginCommand", "options": [ { 
"names": "-h,--help", "description": "Display the help and sub-commands", 
"javaType": "boolean", "type": "boolean" } ], "subcommands": [ { "name": "add", 
"fullName": "plugin add", "description": "Add new plugin", "sourceClass": 
"org.apache.camel.dsl.jbang.core.commands.plugin.PluginA [...]
     { "name": "ps", "fullName": "ps", "description": "List running Camel 
integrations", "sourceClass": 
"org.apache.camel.dsl.jbang.core.commands.process.ListProcess", "options": [ { 
"names": "--json", "description": "Output in JSON Format", "javaType": 
"boolean", "type": "boolean" }, { "names": "--pid", "description": "List only 
pid in the output", "javaType": "boolean", "type": "boolean" }, { "names": 
"--remote", "description": "Break down counters into remote\/total pairs", 
"javaType": [...]
     { "name": "restart", "fullName": "restart", "description": "Restarts 
running Camel integrations (stop + re-launch)", "sourceClass": 
"org.apache.camel.dsl.jbang.core.commands.process.RestartProcess", "options": [ 
{ "names": "-h,--help", "description": "Display the help and sub-commands", 
"javaType": "boolean", "type": "boolean" } ] },
-    { "name": "run", "fullName": "run", "description": "Run as local Camel 
integration", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.Run", 
"options": [ { "names": "--background", "description": "Run in the background", 
"defaultValue": "false", "javaType": "boolean", "type": "boolean" }, { "names": 
"--background-wait", "description": "To wait for run in background to startup 
successfully, before returning", "defaultValue": "true", "javaType": "boolean", 
"type": "boolean" }, { [...]
-    { "name": "sbom", "fullName": "sbom", "description": "Generate a CycloneDX 
or SPDX SBOM for a specific project", "sourceClass": 
"org.apache.camel.dsl.jbang.core.commands.SBOMGenerator", "options": [ { 
"names": "--build-property", "description": "Maven build properties, ex. 
--build-property=prop1=foo", "javaType": "java.util.List", "type": "array" }, { 
"names": "--camel-spring-boot-version", "description": "Camel version to use 
with Spring Boot", "javaType": "java.lang.String", "type" [...]
+    { "name": "run", "fullName": "run", "description": "Run as local Camel 
integration", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.Run", 
"options": [ { "names": "--background", "description": "Run in the background", 
"defaultValue": "false", "javaType": "boolean", "type": "boolean" }, { "names": 
"--background-wait", "description": "To wait for run in background to startup 
successfully, before returning", "defaultValue": "true", "javaType": "boolean", 
"type": "boolean" }, { [...]
+    { "name": "sbom", "fullName": "sbom", "description": "Generate a CycloneDX 
or SPDX SBOM for a specific project", "sourceClass": 
"org.apache.camel.dsl.jbang.core.commands.SBOMGenerator", "options": [ { 
"names": "--build-property", "description": "Maven build properties, ex. 
--build-property=prop1=foo", "javaType": "java.util.List", "type": "array" }, { 
"names": "--camel-spring-boot-version", "description": "Camel version to use 
with Spring Boot", "javaType": "java.lang.String", "type" [...]
     { "name": "script", "fullName": "script", "description": "Run Camel 
integration as shell script for terminal scripting", "sourceClass": 
"org.apache.camel.dsl.jbang.core.commands.Script", "options": [ { "names": 
"--logging", "description": "Can be used to turn on logging (logs to file in 
<user home>\/.camel directory)", "defaultValue": "false", "javaType": 
"boolean", "type": "boolean" }, { "names": "--logging-level", "description": 
"Logging level (ERROR, WARN, INFO, DEBUG, TRACE)", "d [...]
     { "name": "shell", "fullName": "shell", "description": "Interactive Camel 
CLI shell.", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.Shell", 
"options": [ { "names": "-h,--help", "description": "Display the help and 
sub-commands", "javaType": "boolean", "type": "boolean" } ] },
     { "name": "stop", "fullName": "stop", "description": "Shuts down running 
Camel integrations", "sourceClass": 
"org.apache.camel.dsl.jbang.core.commands.process.StopProcess", "options": [ { 
"names": "--kill", "description": "To force killing the process (SIGKILL)", 
"javaType": "boolean", "type": "boolean" }, { "names": "-h,--help", 
"description": "Display the help and sub-commands", "javaType": "boolean", 
"type": "boolean" } ] },
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 a3bd3cbdb8ea..40903035882b 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
@@ -227,7 +227,8 @@ public abstract class ExportBaseCommand extends 
CamelCommand {
     protected boolean observe;
 
     @CommandLine.Option(names = { "--console" }, defaultValue = "false",
-                        description = "Developer console at /q/dev on local 
HTTP server (port 8080 by default). Camel Main runtime only.")
+                        description = "Developer console on the local HTTP 
server (port 8080 by default): /q/dev with Camel Main,"
+                                      + " /actuator/camel with Spring Boot, 
and /q/camel/dev-console with Quarkus")
     protected boolean console;
 
     @CommandLine.Option(names = {
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 7da2264a211e..ce5e54eb588e 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
@@ -60,6 +60,7 @@ import org.apache.camel.util.StringHelper;
 
 import static 
org.apache.camel.dsl.jbang.core.commands.ExportHelper.exportPackageName;
 import static 
org.apache.camel.dsl.jbang.core.common.CamelJBangConstants.CLASSPATH_FILES;
+import static 
org.apache.camel.dsl.jbang.core.common.CamelJBangConstants.CONSOLE;
 
 class ExportQuarkus extends Export {
 
@@ -152,6 +153,18 @@ class ExportQuarkus extends Export {
             if (hawtio) {
                 prop.setProperty("quarkus.hawtio.authenticationEnabled", 
"false");
             }
+            // developer console (--console) is the camel-quarkus-console 
extension (/q/camel/dev-console)
+            if (settingsFlag(settings, CONSOLE)) {
+                if (!prop.containsKey("camel.main.devConsoleEnabled")
+                        && 
!prop.containsKey("camel.main.dev-console-enabled")) {
+                    prop.put("camel.main.devConsoleEnabled", "true");
+                }
+                // the console is only exposed in dev and test mode by 
default, and camel run without --dev runs in
+                // prod mode (quarkus:run). The console has no authentication, 
so this is for local development only.
+                if (!prop.containsKey("quarkus.camel.console.exposure-mode")) {
+                    prop.put("quarkus.camel.console.exposure-mode", "ALL");
+                }
+            }
             return prop;
         });
         // copy docker files
@@ -512,6 +525,11 @@ class ExportQuarkus extends Export {
             answer.add("mvn:org.apache.camel:camel-management");
             answer.add("mvn:io.hawt:hawtio-quarkus:" + hawtioVersion);
         }
+        if (settingsFlag(settings, CONSOLE)) {
+            // developer console (--console) as the camel-quarkus-console 
extension
+            answer.add("mvn:org.apache.camel:camel-console");
+            answer.add("mvn:org.apache.camel:camel-management");
+        }
 
         return answer;
     }
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 42ccfb3e16c0..da1bec69d1af 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
@@ -32,6 +32,7 @@ import java.util.Properties;
 import java.util.Set;
 
 import org.apache.camel.catalog.CamelCatalog;
+import org.apache.camel.dsl.jbang.core.common.CamelJBangConstants;
 import org.apache.camel.dsl.jbang.core.common.CatalogLoader;
 import org.apache.camel.dsl.jbang.core.common.CommandLineHelper;
 import org.apache.camel.dsl.jbang.core.common.PathUtils;
@@ -150,16 +151,23 @@ class ExportSpringBoot extends Export {
             }
             if (hawtio) {
                 // spring boot needs these options configured to support hawtio
-                String s = 
prop.getProperty("management.endpoints.web.exposure.include");
-                if (s == null) {
-                    s = "hawtio,jolokia";
-                } else {
-                    s = s + ",hawtio,jolokia";
-                }
-                prop.setProperty("management.endpoints.web.exposure.include", 
s);
+                exposeActuatorEndpoints(prop, "hawtio,jolokia");
                 prop.setProperty("spring.jmx.enabled", "true");
                 prop.setProperty("hawtio.authenticationEnabled", "false");
             }
+            // developer console (--console) is the camel actuator endpoint 
(/actuator/camel)
+            if (settingsFlag(settings, CamelJBangConstants.CONSOLE)) {
+                if (!prop.containsKey("camel.main.devConsoleEnabled")
+                        && 
!prop.containsKey("camel.main.dev-console-enabled")) {
+                    prop.put("camel.main.devConsoleEnabled", "true");
+                }
+                if (observe && 
!prop.containsKey("management.endpoints.web.exposure.include")) {
+                    // camel-observability-services-starter exposes health and 
prometheus as its default, which an
+                    // explicit exposure list would replace, so keep them (the 
console is then at /observe/camel)
+                    exposeActuatorEndpoints(prop, "health,prometheus");
+                }
+                exposeActuatorEndpoints(prop, "camel");
+            }
             return prop;
         });
         createMavenPom(settings, profile, buildDir.resolve("pom.xml"), deps);
@@ -424,10 +432,29 @@ class ExportSpringBoot extends Export {
             String hawtioArtifact = springBootVersion.startsWith("4.") ? 
"hawtio-springboot4" : "hawtio-springboot";
             answer.add("mvn:io.hawt:" + hawtioArtifact + ":" + hawtioVersion);
         }
+        if (settingsFlag(settings, CamelJBangConstants.CONSOLE)) {
+            // developer console (--console) as actuator endpoint 
(camel-console-starter)
+            answer.add("mvn:org.apache.camel:camel-console");
+            answer.add("mvn:org.apache.camel:camel-management");
+        }
 
         return answer;
     }
 
+    /**
+     * Adds the given actuator endpoint ids to {@code 
management.endpoints.web.exposure.include}, keeping the ids that
+     * are already exposed.
+     */
+    private static void exposeActuatorEndpoints(Properties prop, String ids) {
+        String s = 
prop.getProperty("management.endpoints.web.exposure.include");
+        if (s == null || s.isBlank()) {
+            s = ids;
+        } else {
+            s = s + "," + ids;
+        }
+        prop.setProperty("management.endpoints.web.exposure.include", s);
+    }
+
     private void createMainClassSource(Path srcJavaDir, String packageName, 
String mainClassname) throws Exception {
         Map<String, Object> model = new HashMap<>();
         model.put("PackageName", packageName);
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 33cf67066483..0f3c07456f30 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
@@ -1590,6 +1590,8 @@ public class Run extends CamelCommand {
         eq.ignoreLoadingError = this.ignoreLoadingError;
         eq.lazyBean = this.lazyBean;
         eq.profile = this.profile;
+        eq.observe = this.serverOptions.observe;
+        eq.console = this.serverOptions.console;
         eq.applicationProperties = this.property;
 
         printer().println("Running using Quarkus (preparing and downloading 
files)");
@@ -2319,6 +2321,8 @@ public class Run extends CamelCommand {
         eq.ignoreLoadingError = this.ignoreLoadingError;
         eq.lazyBean = this.lazyBean;
         eq.profile = this.profile;
+        eq.observe = this.serverOptions.observe;
+        eq.console = this.serverOptions.console;
         eq.applicationProperties = this.property;
 
         printer().println("Running using Spring Boot (preparing and 
downloading files)");
@@ -3570,7 +3574,9 @@ public class Run extends CamelCommand {
         int managementPort = -1;
 
         @Option(names = { "--console" }, defaultValue = "false",
-                description = "Developer console at /q/dev on local HTTP 
server (port 8080 by default)")
+                description = "Developer console on the local HTTP server 
(port 8080 by default): /q/dev with the jbang"
+                              + " and Camel Main runtimes, /actuator/camel 
with Spring Boot, and /q/camel/dev-console"
+                              + " with Quarkus")
         boolean console;
 
         @Option(names = { "--mcp" }, defaultValue = "false",
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 13d28cab8c4f..d79c259aaa9e 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
@@ -861,37 +861,101 @@ class ExportTest {
                 containsDependency(model.getDependencies(), 
"org.apache.camel", "camel-ai-observability", null));
     }
 
+    @ParameterizedTest
+    @MethodSource("runtimeProvider")
+    public void shouldExportConsole(RuntimeType rt) throws Exception {
+        LOG.info("shouldExportConsole {}", rt);
+        Export command = new Export(new CamelJBangMain());
+        List<String> cmdArgs = new ArrayList<>(
+                List.of("--gav=examples:route:1.0.0", "--dir=" + workingDir, 
"--quiet",
+                        "--runtime=%s".formatted(rt.runtime()), "--console"));
+        if (rt == RuntimeType.springBoot) {
+            cmdArgs.add("--camel-version=" + RELEASED_CAMEL_VERSION);
+        }
+        cmdArgs.add("target/test-classes/route.yaml");
+        CommandLine.populateCommand(command, cmdArgs.toArray(String[]::new));
+        int exit = command.doCall();
+
+        Assertions.assertEquals(0, exit);
+        Model model = readMavenModel();
+        Properties props = new Properties();
+        try (FileInputStream fis = new FileInputStream(new File(workingDir, 
"src/main/resources/application.properties"))) {
+            props.load(fis);
+        }
+        // the developer console is enabled with the same camel-main option on 
all runtimes
+        Assertions.assertEquals("true", exportedProperty(props, 
"camel.main.devConsoleEnabled"));
+        // internal camel-jbang settings must not leak into the exported 
project
+        Assertions.assertNull(props.getProperty("camel.jbang.console"));
+
+        if (rt == RuntimeType.main) {
+            for (String artifact : List.of("camel-console", 
"camel-management", "camel-health",
+                    "camel-platform-http-main", 
"camel-platform-http-jolokia")) {
+                
Assertions.assertTrue(containsDependency(model.getDependencies(), 
"org.apache.camel", artifact, null),
+                        "Missing dependency " + artifact);
+            }
+            for (String key : List.of("camel.management.enabled", 
"camel.management.devConsoleEnabled",
+                    "camel.management.healthCheckEnabled", 
"camel.management.infoEnabled",
+                    "camel.management.jolokiaEnabled")) {
+                Assertions.assertEquals("true", exportedProperty(props, key), 
"Missing property " + key);
+            }
+        } else if (rt == RuntimeType.springBoot) {
+            // the console is the camel actuator endpoint, which must be 
exposed over the web
+            for (String artifact : List.of("camel-console-starter", 
"camel-management-starter")) {
+                Assertions.assertTrue(
+                        containsDependency(model.getDependencies(), 
"org.apache.camel.springboot", artifact, null),
+                        "Missing dependency " + artifact);
+            }
+            Assertions.assertEquals("camel", 
props.getProperty("management.endpoints.web.exposure.include"));
+        } else if (rt == RuntimeType.quarkus) {
+            // the console extension only exposes the console in dev and test 
mode unless told otherwise
+            for (String artifact : List.of("camel-quarkus-console", 
"camel-quarkus-management")) {
+                Assertions.assertTrue(
+                        containsDependency(model.getDependencies(), 
"org.apache.camel.quarkus", artifact, null),
+                        "Missing dependency " + artifact);
+            }
+            Assertions.assertEquals("ALL", 
props.getProperty("quarkus.camel.console.exposure-mode"));
+        }
+    }
+
     @Test
-    public void shouldExportConsoleForCamelMain() throws Exception {
+    public void shouldExposeConsoleWithObserveOnSpringBoot() throws Exception {
         Export command = new Export(new CamelJBangMain());
         CommandLine.populateCommand(command,
                 "--gav=examples:route:1.0.0",
                 "--dir=" + workingDir,
                 "--quiet",
-                "--runtime=main",
-                "--console",
+                "--runtime=spring-boot", "--camel-version=" + 
RELEASED_CAMEL_VERSION,
+                "--console", "--observe",
                 "target/test-classes/route.yaml");
         int exit = command.doCall();
 
         Assertions.assertEquals(0, exit);
-        Model model = readMavenModel();
-        for (String artifact : List.of("camel-console", "camel-management", 
"camel-health",
-                "camel-platform-http-main", "camel-platform-http-jolokia")) {
-            Assertions.assertTrue(containsDependency(model.getDependencies(), 
"org.apache.camel", artifact, null),
-                    "Missing dependency " + artifact);
+        Properties props = new Properties();
+        try (FileInputStream fis = new FileInputStream(new File(workingDir, 
"src/main/resources/application.properties"))) {
+            props.load(fis);
         }
+        // the observability defaults must survive the explicit exposure list
+        Assertions.assertEquals("health,prometheus,camel", 
props.getProperty("management.endpoints.web.exposure.include"));
+    }
 
+    @Test
+    public void shouldExposeConsoleWithHawtioOnSpringBoot() throws Exception {
+        Export command = new Export(new CamelJBangMain());
+        CommandLine.populateCommand(command,
+                "--gav=examples:route:1.0.0",
+                "--dir=" + workingDir,
+                "--quiet",
+                "--runtime=spring-boot", "--camel-version=" + 
RELEASED_CAMEL_VERSION,
+                "--console", "--hawtio",
+                "target/test-classes/route.yaml");
+        int exit = command.doCall();
+
+        Assertions.assertEquals(0, exit);
         Properties props = new Properties();
         try (FileInputStream fis = new FileInputStream(new File(workingDir, 
"src/main/resources/application.properties"))) {
             props.load(fis);
         }
-        for (String key : List.of("camel.main.devConsoleEnabled", 
"camel.management.enabled",
-                "camel.management.devConsoleEnabled", 
"camel.management.healthCheckEnabled",
-                "camel.management.infoEnabled", 
"camel.management.jolokiaEnabled")) {
-            Assertions.assertEquals("true", exportedProperty(props, key), 
"Missing property " + key);
-        }
-        // internal camel-jbang settings must not leak into the exported 
project
-        Assertions.assertNull(props.getProperty("camel.jbang.console"));
+        Assertions.assertEquals("hawtio,jolokia,camel", 
props.getProperty("management.endpoints.web.exposure.include"));
     }
 
     @Test

Reply via email to