[
https://issues.apache.org/jira/browse/CAMEL-26371?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Claus Ibsen resolved CAMEL-26371.
---------------------------------
Resolution: Fixed
Fixed by https://github.com/apache/camel/pull/28624 (merged as
09d8d5f8564198c13a234d4fca924452504f3433), thanks Ricardo.
_Claude Code on behalf of davsclaus_
> {{camel run --runtime=camel-main --local-kamelet-dir=<dir1>,<dir2>}} fails to
> resolve kamelets when more than one directory is supplied (regression since
> 4.23.0).
> ------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-26371
> URL: https://issues.apache.org/jira/browse/CAMEL-26371
> Project: Camel
> Issue Type: Bug
> Components: camel-jbang
> Reporter: Ricardo Martinez
> Priority: Trivial
> Fix For: 4.24.0
>
>
> h2. Description
> Routes using local kamelets fail to start when \{{--runtime=camel-main}} is
> combined with a comma-separated \{{--local-kamelet-dir}} value containing
> more than one path. The same command works fine with a single directory, and
> worked with multiple directories in 4.22 and earlier.
> h3. Reproduction
> *Fails — kamelets not found:*
> {code:bash}
> camel run demo.camel.yaml \
> --runtime=camel-main \
> --local-kamelet-dir=/home/user/project,/home/user/project/kamelets
> {code}
> *Works — single directory is fine:*
> {code:bash}
> camel run demo.camel.yaml \
> --runtime=camel-main \
> --local-kamelet-dir=/home/user/project/kamelets
> {code}
> h3. Root Cause
> Commit \{{935f581a8a59}} (CAMEL-24659, released in 4.23.0) changed
> \{{--runtime=camel-main}} to export sources to a temporary Maven project,
> build a fat JAR, and launch it. This routes execution through
> \{{ExportBaseCommand.copySourceFiles()}}, which has two bugs that surface
> only when \{{LOCAL_KAMELET_DIR}} contains more than one comma-separated path.
> *Bug 1 — scheme stripped from the entire comma-joined string*
> {\{getScheme()}} finds the first \{{:}} in the whole concatenated string and
> strips the scheme prefix from that position. With a multi-directory value
> like \{{file:/path/a,file:/path/b}}, only the \{{file:}} from the first entry
> is removed; subsequent entries retain their \{{file:}} prefix and are passed
> as-is to \{{Paths.get()}}.
> {code:java}
> // BROKEN — value: "file:/home/user/project,file:/home/user/project/kamelets"
> String localKameletDir = prop.getProperty(LOCAL_KAMELET_DIR);
> if (localKameletDir != null) {
> String scheme = getScheme(localKameletDir); // returns "file" (finds first
> ":")
> if (scheme != null) {
> localKameletDir = localKameletDir.substring(scheme.length() + 1);
> // result: "/home/user/project,file:/home/user/project/kamelets"
> // ^^^^^ second entry still has "file:" prefix
> }
> }
> {code}
> *Bug 2 — \{{Paths.get()}} called with the corrupted (unsplit) string*
> {code:java}
> // BROKEN — localKameletDir still contains a literal comma and a leftover
> "file:" prefix
> source = Paths.get(localKameletDir, f + ".kamelet.yaml");
> // = Paths.get("/home/user/project,file:/home/user/project/kamelets",
> "my-kamelet.kamelet.yaml")
> // Resolved path contains a literal comma and does not exist on disk.
> {code}
> h3. Affected File
> {\{dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportBaseCommand.java}}
> — method \{{copySourceFiles()}}.
> h3. Fix
> Replace the single \{{localKameletDir}} string variable with a
> \{{List<String>}}, stripping the \{{file:}} scheme from *each element
> individually*, and update the kamelet-file lookup to search across all
> directories in order (falling back to the first entry if none is found, which
> preserves the existing error behaviour for genuinely missing kamelets). No
> new imports are required — \{{List}}, \{{ArrayList}}, \{{Paths}}, and
> \{{Files}} are already imported.
> {code:java}
> // FIXED — strip scheme per element
> List<String> localKameletDirs = new ArrayList<>();
> String localKameletDirRaw = prop.getProperty(LOCAL_KAMELET_DIR);
> if (localKameletDirRaw != null) {
> for (String part : localKameletDirRaw.split(",")) {
> String scheme = getScheme(part);
> if (scheme != null) {
> part = part.substring(scheme.length() + 1);
> }
> localKameletDirs.add(part);
> }
> }
> // FIXED — search each directory in order
> if ("kamelet".equals(k) && !localKameletDirs.isEmpty()) {
> String kameletFileName = f + ".kamelet.yaml";
> source = localKameletDirs.stream()
> .map(dir -> Paths.get(dir, kameletFileName))
> .filter(Files::exists)
> .findFirst()
> .orElse(Paths.get(localKameletDirs.get(0), kameletFileName));
> }
> {code}
> h3. Workarounds (until the fix is released)
> * Use \{{--runtime=jbang}} (the old in-process default). The \{{KameletMain}}
> codepath still handles multiple directories correctly.
> * Pass only one kamelet directory — the most specific one (e.g. the
> \{{kamelets/}} subdirectory).
> ----
> _Filed by Bob (AI) on behalf of lordrip._
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)