[agent] Filed by Claude Code on behalf of Mikola Lysenko (@mikolalysenko) while adding Maven patch SBOM annotations to depscan. Repro artifacts were produced with real Maven and a stub patch API.
Summary
find_maven_dependency_matches matches on groupId + artifactId only. It reads <type> but never <classifier>. A hosted grant is for the main jar only: the served maven2 tail exposes only <a>-<sfx>.jar/.pom and their sidecars. Even so, every classifier variant of the same GA whose literal version equals the base gets rewritten to <base>-socket.<hex8>. Examples of such variants: sources, tests, javadoc, and native classifiers like linux-x86_64.
Impact
- Broken builds. The suffixed classifier artifact does not exist anywhere. The Socket repo 404s
…-socket.<hex8>-sources.jar, and Central has no such version.
- Silent fail-open when the main jar is only transitive. Take a pom that declares only a classifier variant, while the main jar comes in transitively. The classifier literal counts as "versioned", so no
<dependencyManagement> pin is added for the main jar. The main jar then resolves unpatched from Central.
Real-world shapes this hits:
- netty native transports (
netty-transport-native-epoll:linux-x86_64)
-tests jars
sources for IDE builds
Repro
The grant is the same one as in the basic golden, for org.apache.commons:commons-lang3:3.12.0 → 3.12.0-socket.4d5e6f70. Run scan --mode hosted --json --yes, then Maven 3.9.6 dependency:3.6.1:copy-dependencies, with the stub Socket repo mirrored in via settings.xml.
Case 1, the main jar plus a sources jar. Both <version>3.12.0</version> lines get rewritten:
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.12.0</version></dependency>
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.12.0</version><classifier>sources</classifier></dependency>
Results:
- Scan:
redirected: 1, no warnings.
- Maven fetches the patched main jar from the Socket repo, then requests
…/3.12.0-socket.4d5e6f70/commons-lang3-3.12.0-socket.4d5e6f70-sources.jar (404). BUILD FAILURE.
- On 3.9.6 the error surfaces as
Cannot invoke "org.eclipse.aether.artifact.Artifact.isSnapshot()" …, because of a resolver NPE with trusted checksums enabled. On 3.8.9/3.9.16 it is Could not find artifact.
Case 2, only the sources classifier is declared, and the main jar is transitive via commons-text:1.10.0:
- Scan:
redirected: 1.
- Maven downloads
commons-lang3-3.12.0.jar (unpatched) from Central, and the build then fails on the suffixed sources jar.
- With the build fixed by hand (sources dep reverted), the project is silently unpatched, because no depMgmt pin was ever added.
Expected vs actual
- Expected: only a
<dependency> with no <classifier> (or an empty one) and type jar is the grant's target.
- A classifier variant with the base literal is left alone, with a warning (for example
redirect_maven_classifier_unsupported).
- The main-jar decision (literal rewrite vs. depMgmt pin) is made from the classifier-less matches only.
- Actual: every classifier variant is suffixed, and the depMgmt fallback is suppressed.
CLI revision
3efdc31d
Suggested fix
- Capture
<classifier> in MavenDependencyMatch.
- Filter matches to
classifier.is_none() && type in {None, "jar"} before the versioned / depMgmt logic.
- Warn on the others.
- Add goldens
classifier-sources-sibling and classifier-only-transitive-main.
- Mirror the change in the depscan TS twin.
File refs (at 3efdc31)
crates/socket-patch-core/src/patch/redirect/mod.rs:5840-5899 (MavenDependencyMatch has no classifier; find_maven_dependency_matches)
crates/socket-patch-core/src/patch/redirect/mod.rs:6090-6170 (the versioned / depMgmt decision)
[agent] Filed by Claude Code on behalf of Mikola Lysenko (@mikolalysenko) while adding Maven patch SBOM annotations to depscan. Repro artifacts were produced with real Maven and a stub patch API.
Summary
find_maven_dependency_matchesmatches ongroupId+artifactIdonly. It reads<type>but never<classifier>. A hosted grant is for the main jar only: the served maven2 tail exposes only<a>-<sfx>.jar/.pomand their sidecars. Even so, every classifier variant of the same GA whose literal version equals the base gets rewritten to<base>-socket.<hex8>. Examples of such variants:sources,tests,javadoc, and native classifiers likelinux-x86_64.Impact
…-socket.<hex8>-sources.jar, and Central has no such version.<dependencyManagement>pin is added for the main jar. The main jar then resolves unpatched from Central.Real-world shapes this hits:
netty-transport-native-epoll:linux-x86_64)-testsjarssourcesfor IDE buildsRepro
The grant is the same one as in the
basicgolden, fororg.apache.commons:commons-lang3:3.12.0→3.12.0-socket.4d5e6f70. Runscan --mode hosted --json --yes, then Maven 3.9.6dependency:3.6.1:copy-dependencies, with the stub Socket repo mirrored in viasettings.xml.Case 1, the main jar plus a sources jar. Both
<version>3.12.0</version>lines get rewritten:Results:
redirected: 1, no warnings.…/3.12.0-socket.4d5e6f70/commons-lang3-3.12.0-socket.4d5e6f70-sources.jar(404). BUILD FAILURE.Cannot invoke "org.eclipse.aether.artifact.Artifact.isSnapshot()" …, because of a resolver NPE with trusted checksums enabled. On 3.8.9/3.9.16 it isCould not find artifact.Case 2, only the
sourcesclassifier is declared, and the main jar is transitive viacommons-text:1.10.0:redirected: 1.commons-lang3-3.12.0.jar(unpatched) from Central, and the build then fails on the suffixed sources jar.Expected vs actual
<dependency>with no<classifier>(or an empty one) and typejaris the grant's target.redirect_maven_classifier_unsupported).CLI revision
3efdc31dSuggested fix
<classifier>inMavenDependencyMatch.classifier.is_none() && type in {None, "jar"}before the versioned / depMgmt logic.classifier-sources-siblingandclassifier-only-transitive-main.File refs (at 3efdc31)
crates/socket-patch-core/src/patch/redirect/mod.rs:5840-5899(MavenDependencyMatchhas no classifier;find_maven_dependency_matches)crates/socket-patch-core/src/patch/redirect/mod.rs:6090-6170(the versioned / depMgmt decision)