davsclaus opened a new pull request, #28688:
URL: https://github.com/apache/camel/pull/28688

   _Claude Code on behalf of davsclaus_
   
   Stage 1c-1 of 
[CAMEL-24727](https://issues.apache.org/jira/browse/CAMEL-24727), stacked on 
#28675 (and so on #28671): retarget to `main` once those merge.
   
   `camel-jbang-export` is the engine that `camel export` and `camel run` use, 
and its Java API is for tools such as Kaoto that export without the CLI. This 
PR makes an export keep to its request and leave the JVM as it found it, so an 
application can export many times, and several exports can run at the same 
time. There are no CLI-only or API-only branches: the CLI sets up what it needs 
(logging, system properties) before it calls the engine.
   
   ## Changes
   
   - **Work directory per request.** `ExportRequest.workDir` holds the run 
settings of the silent run and the project being built. The default is 
`.camel-jbang` in the current directory, as before. The silent `Run` writes its 
settings, compile dir and generated OpenAPI file there.
   - **No logging configuration in the engine.** The silent run of an export no 
longer calls `RuntimeUtil.configureLog`, which reconfigured log4j for the whole 
JVM and set system properties. `camel export` already configures logging before 
it exports. In the CLI, the second call only reset the root level, back to 
`info`, which ignored `--logging-level` of the export.
   - **No system properties in the engine.** `ProjectExporter.prepare` no 
longer reads them. `ExportBaseCommand.applySystemProperties` maps them onto the 
request for `camel export`, `camel dependency`/`sbom` and `camel run 
--runtime=...`:
     - `camel.jbang.camelSpringBootVersion`
     - the Quarkus platform properties
     - `camel.jbang.repos`, which now also reaches the downloads of the silent 
run, not only the pom.xml
   
     The `camel.jbang.quarkus.platform.url` fallback moves to the CLI option of 
the Quarkus Extension Registry. `CatalogLoader.loadSpringBootCatalog` gets an 
overload with an explicit provider version.
   - **Extra default repositories as an option.** `MavenDownloader` gets 
`setExtraRepos`/`getExtraRepos`. The precedence is:
     1. the configured value (empty means none);
     2. the `camel.extra.repos` system property;
     3. `camel.default.extra.repos.default.value`.
   
     The first one set wins. `MavenResolver` carries the value, 
`KameletMain`/`MavenDependencyDownloader` pass it to the downloader of the 
silent run, and the exporter puts the repositories the downloads use into the 
pom.xml. The CLI leaves it unset, so the system properties work as before.
   - **An export releases its silent run.** Every export kept its whole silent 
run (`Run`, `KameletMain`, `CamelContext`, about 0.6 MB each) for the life of 
the JVM. A heap dump showed two GC roots:
     - The default shutdown strategy of Camel Main adds a JVM shutdown hook 
that is never removed. The silent run of an export now uses 
`SimpleMainShutdownStrategy`.
     - The static `ProcessorReifier` registry held the transacted reifier of 
`TransactedDownloader`, which captured the `KameletMain` that registered it. It 
now binds the policies in the registry of the route's `CamelContext`, which is 
the same `MainRegistry`.
   - **Kamelet catalog cache.** Two threads that loaded a released catalog at 
the same time each put their own map in the cache, so the callers did not share 
one (the concurrent test classes made `KameletCatalogHelperTest` flaky). It now 
uses `putIfAbsent`.
   - **Docs.** The "Exporting from Java" section of `camel-jbang-projects.adoc` 
describes the above.
   
   ## Tests
   
   - `ProjectExporterTest` (export, stub resolver):
     - 4 exports in parallel, each with its own work dir, and `./.camel-jbang` 
untouched;
     - `prepare` reads no system properties;
     - explicit, empty and system-property extra repos in the pom.xml.
   - `ExportApiTest` (core, the real silent run):
     - the log4j configuration and the system properties are the same after an 
export (this fails on the old code);
     - 20 exports in a row: their `CamelContext`s are all garbage collected 
(checked with `CamelContextTracker` and weak references), and no threads are 
left (this fails without the shutdown strategy fix).
   - `MavenDownloaderImplTest.testExtraReposPrecedence`.
   
   I ran these suites locally, and they all pass:
   
   | Module | Tests |
   |---|---|
   | camel-tooling-maven | 38 (14 skipped) |
   | camel-kamelet-main | 66 |
   | camel-jbang-export | 109 (3 more runs with retries off) |
   | camel-jbang-core | 2417 + 242 serial |
   | camel-jbang-plugin-kubernetes | 156 |
   | camel-jbang-plugin-validate | 23 |
   | camel-jbang-plugin-test | 6 |
   | camel-jbang-mcp | 505 |
   | camel-jbang-plugin-tui | 2283 |
   | camel-launcher | 292 (36 skipped) |
   
   The generate and mcp plugins also build. The one exception is 
`EvalSimpleTest`, which fails the same way on `main`: it runs the Camel 
installed with JBang, not this build. I did not run the camel-jbang-it 
integration tests. The builds left no generated files to commit.
   
   Not changed here, and left for 1c-2/1c-3: the transform runs of `camel 
transform` (and the TUI) boot `KameletMain` with the default shutdown strategy 
too, and the silent run still sets the static printer of `CommandHelper` (a 
ThreadLocal of the calling thread).
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to