[
https://issues.apache.org/jira/browse/CAMEL-25921?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18129591#comment-18129591
]
Federico Mariani commented on CAMEL-25921:
------------------------------------------
_Claude Code on behalf of Croway_
Reproduced, and fixed in https://github.com/apache/camel/pull/28239 (main) and
https://github.com/apache/camel/pull/28240 (camel-4.22.x backport, straight
cherry-pick).
h3. Reproduction
Camel JBang 4.22.1 CLI, isolated user home, {{camel plugin add forage --gav
io.kaoto.forage:camel-jbang-plugin-forage:1.6.1}} then {{camel forage --help}}:
||Local repository written by||4.22.1||with the fix||
|Maven 3.10.0|2 classpath entries, NoClassDefFoundError|47 entries, plugin
loads|
|Maven 3.9.12|46 entries ({{snakeyaml}} missing), plugin loads|47 entries,
plugin loads|
Maven 3.10.0 wrote 629 URL-qualified tracking entries and no ID-only ones. Note
that a 4.24.0-SNAPSHOT CLI does not show the problem: its SNAPSHOT parent POM
makes the offline attempt fail early, so it always falls back online.
h3. Root causes
# The embedded Maven Resolver 1.9 only recognizes ID-only tracking keys
({{file>central=}}), not the URL-qualified keys of Maven 3.10
({{file>central-<sha1(url)>=}}). Cached artifacts are then verified again
remotely, and {{--offline}} fails. The hash cannot simply be recomputed: Maven
hashes the URL it knows the repository by ({{repo.maven.apache.org}}), while
Camel uses {{repo1.maven.org}}.
# {{preferLocal}} (CAMEL-23334, 4.20+) resolved offline first, then online on
failure. A POM that could not be read offline was silently ignored (no
dependencies, no exception). When the offline attempt did fail, the online
retry reused that empty descriptor from the session cache it shared with the
offline attempt. This part is *not* specific to Maven 3.10: with a Maven 3.9
repository, 4.22.1 dropped {{snakeyaml}} from the Forage classpath.
h3. Fix
* A local repository manager wrapper (standalone mode only) also accepts
{{<repoId>-<sha1>}} entries for the requested repository id, at the same trust
level as the ID-only entries. This is also what Maven Resolver 2.0.23 does with
ID-only entries. What Camel writes is unchanged, and Maven 3.9 and 3.10 both
read it.
* {{preferLocal}} now resolves once with update policy {{never}} (like {{mvn
--no-snapshot-updates}}), with no offline attempt and no fallback.
Upgrading the embedded resolver to 2.x was ruled out:
{{camel-report-maven-plugin}} and {{MavenVersionManager}} run in embedded mode,
inside the user's Maven, which can still be Maven 3.9 / Resolver 1.9. No
upgrade guide entry is needed: no default, option or API changes. 4.18.x
predates MIMA and {{preferLocal}}, so only the first cause applies there, and
it would need a hand-adapted port.
The workaround in the description
({{-Daether.system.trackingRepositoryKeyFunction=nid}}) remains valid for
released versions.
> camel-jbang - plugins resolve with no dependencies (or are re-downloaded)
> when the local Maven repository was written by Maven 3.10
> -----------------------------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-25921
> URL: https://issues.apache.org/jira/browse/CAMEL-25921
> Project: Camel
> Issue Type: Bug
> Components: camel-jbang
> Affects Versions: 4.18.4, 4.20.0, 4.22.1
> Reporter: Federico Mariani
> Assignee: Federico Mariani
> Priority: Major
>
> Since Maven 3.10.0 (Maven Resolver 2.0.23+), the local repository tracking
> files ({{_remote.repositories}}) record artifact provenance with a
> URL-qualified repository key, e.g.
> {noformat}
> langchain4j-bom-1.13.0.pom>central-8fac3ebd6edbaca3c794783fa38088af0aa128e7=
> {noformat}
> instead of the legacy ID-only key ({{langchain4j-bom-1.13.0.pom>central=}}).
> This is the new default of {{aether.system.trackingRepositoryKeyFunction}}
> ({{nid_hurl}}), introduced as hardening against local repository poisoning.
> {{camel-tooling-maven}} embeds Maven Resolver 1.9.27 (via MIMA), which only
> understands ID-only entries. With a local repository populated by Maven 3.10,
> every cached artifact is considered "not downloaded from this repository
> before", which leads to two problems in Camel JBang plugin resolution.
> h3. 1. Offline-first plugin resolution silently returns no dependencies
> (4.20+ / 4.22)
> {{PluginHelper.downloadPlugin}} sets {{preferLocal=true}}, so
> {{MavenDownloaderImpl.resolveArtifacts}} first resolves offline when the
> requested GAV exists in the local repository. When the plugin POM model
> cannot be built offline (e.g. its parent imports BOMs that are "invisible"
> because of the tracking keys above), Maven Resolver's default
> {{ArtifactDescriptorPolicy}} ignores the missing/invalid descriptor and
> returns the plugin with *no* transitive dependencies. No exception is thrown,
> so the online fallback never runs, and {{writeCache}} persists the incomplete
> classpath in {{~/.camel-jbang-plugins.json}}:
> {noformat}
> "classpath": [
> ".../camel-jbang-parent-4.22.1.pom",
> ".../camel-jbang-plugin-forage-1.6.2-SNAPSHOT.jar"
> ]
> {noformat}
> Loading the plugin then fails while picocli reflects the command classes:
> {noformat}
> Exception in thread "main" java.lang.NoClassDefFoundError:
> io/kaoto/forage/catalog/reader/ForageCatalogReader$FactoryMetadata
> at java.base/java.lang.Class.getDeclaredMethods0(Native Method)
> ...
> at picocli.CommandLine.<init>(CommandLine.java:199)
> at io.kaoto.forage.plugin.ForagePlugin.customize(ForagePlugin.java:33)
> at
> org.apache.camel.dsl.jbang.core.common.PluginHelper.addPlugins(PluginHelper.java:179)
> at
> org.apache.camel.dsl.jbang.core.commands.CamelJBangMain.execute(CamelJBangMain.java:245)
> {noformat}
> The same resolution with a local repository written by Maven 3.9 resolves 46
> classpath entries and the plugin loads.
> h3. 2. Everything is re-downloaded (4.18.x)
> Without the offline-first path, the resolver logs "Artifact ... is present in
> the local repository, but cached from a remote repository ID that is
> unavailable in current build context" for every artifact and downloads it
> again, making plugin/dependency resolution much slower.
> h3. Reproducer
> Linux container ({{eclipse-temurin:21-jdk}}), Maven 3.10.0, Camel JBang
> 4.22.1, any third-party plugin whose POM parent imports BOMs (here: Kaoto
> Forage, {{io.kaoto.forage:camel-jbang-plugin-forage}}):
> {noformat}
> # 1. populate ~/.m2 with Maven 3.10.0 (e.g. build a project /
> dependency:resolve)
> mvn -B -DskipTests verify ...
> grep -v '^#'
> ~/.m2/repository/dev/langchain4j/langchain4j-bom/1.13.0/_remote.repositories
> #
> langchain4j-bom-1.13.0.pom>central-8fac3ebd6edbaca3c794783fa38088af0aa128e7=
> # 2. add and load the plugin
> jbang -Dcamel.jbang.version=4.22.1 camel@apache/camel plugin add forage --gav
> io.kaoto.forage:camel-jbang-plugin-forage:<version>
> jbang -Dcamel.jbang.version=4.22.1 camel@apache/camel forage --help
> # NoClassDefFoundError (plugin classpath = parent pom + plugin jar only)
> {noformat}
> Running step 1 with
> {{MAVEN_ARGS=-Daether.system.trackingRepositoryKeyFunction=nid}} (legacy
> tracking) makes step 2 work.
> This hits CI first: GitHub-hosted runners now ship Maven 3.10.0, so any job
> whose Maven cache is (re)built by Maven 3.10 breaks, while jobs restoring an
> older cache keep working.
> h3. Suggested fixes
> * Upgrade the Maven Resolver embedded in {{camel-tooling-maven}} to 2.0.23+
> (which reads both legacy and URL-qualified tracking entries), or configure
> the tracking key function of the embedded session accordingly.
> * In {{MavenDownloaderImpl}}, do not treat an offline resolution as
> successful when the root artifact's descriptor could not be read (or resolved
> with no dependencies although the POM declares some): fall back to online
> resolution instead, and avoid caching such a classpath in
> {{PluginHelper.writeCache}}.
> h3. Workaround
> Set {{-Daether.system.trackingRepositoryKeyFunction=nid}} for the Maven
> builds that populate the local repository used by Camel JBang (e.g.
> {{MAVEN_ARGS}} in CI).
--
This message was sent by Atlassian Jira
(v8.20.10#820010)