[MNG-1378] make test-jar dependencies transitive - #13066
Conversation
Treat the direct test-scoped dependencies of a test-jar producer as part of that test artifact's dependency contract when resolving under Maven 4 semantics. Keep ordinary test-scope behavior unchanged, preserve Maven 3 personality compatibility, and add an integration fixture that proves the test-jar consumer receives the producer's test dependency while a regular JAR consumer does not. Signed-off-by: Robert McConnell <robert@mcc0nnell.org>
06e2472 to
a022b55
Compare
|
@hboutemy, when you have a moment, I’d especially value your take on the semantics here. I kept this Maven 4-only and artifact-specific so ordinary test scope remains non-transitive; the key question is whether a consumed test-jar should carry the producer’s direct test-scoped dependencies as part of its dependency contract. If the direction is sound, I’m happy to adjust the implementation or tests to fit Maven’s preferred layer. |
|
Thanks for the PR — this addresses a long-standing gap (21 years, 71 votes, 5 duplicates). On the direction: I think this is the right approach. The core insight is that a The counter-argument that "tests are not public" only holds when there is no test-jar. If you don't want test code to be reusable, you simply don't create one. But once you do, the current behavior is the worst of both worlds: Maven lets you publish the artifact but silently drops the dependencies it needs to function, forcing every consumer to manually reduplicate them. The approach here — a narrowly-scoped, Maven-4-only decorator that only allows direct test-scoped children through when resolving a A few things to address before this can move forward:
|
|
One additional thought: this PR targets I'd suggest adding a feature flag in public static boolean testJarTransitiveDeps(@Nullable Map<String, ?> userProperties) {
return doGet(userProperties, Constants.MAVEN_TEST_JAR_TRANSITIVE_DEPS, !mavenMaven3Personality(userProperties));
}This way it:
This gives users a safety valve if the new transitive deps break their build, and keeps the Maven 3 personality handling clean — just a different default for the same feature flag. |
Summary
Fixes MNG-1378 for Maven 4 by making a producer's direct test-scoped dependencies available when that producer is consumed as a dependency of type
test-jar.Maven's normal test scope remains non-transitive. The change is deliberately artifact-specific: the scope selector is wrapped with a parent-aware selector that permits test dependencies only while collecting the children of a
test-jarartifact. Ordinary JAR dependencies keep the existing behavior.Why
A
test-jaris a separate artifact with its own classpath requirements. Its classes may depend on libraries declared withscope=testin the producer POM, but those libraries are currently dropped when another project consumes the test JAR.As a result, consumers must manually duplicate dependencies that are already part of the producer's test classpath. This is the behavior reported by MNG-1378.
Implementation
The change adds a
TestJarDependencySelectoraround Maven's existing scope selector.The selector is parent-aware: when Resolver descends into a dependency whose artifact type is exactly
test-jar, direct test-scoped children are allowed through. Everywhere else, dependency selection delegates unchanged to Maven's existing scope rules.The implementation does not:
Compatibility
The behavior change applies only to Maven 4 semantics.
Maven-3-personality mode keeps the existing selector unchanged. This avoids changing long-established Maven 3 dependency behavior while allowing Maven 4 to give
test-jarartifacts a dependency graph that matches their actual classpath requirements.Tests
This PR adds a Core IT regression fixture with four modules:
supporttest-jarsupportwithscope=testconsumertest-jarand must receive both the test JAR andsupportregular-consumersupportThe producer artifacts are installed before the consumers are resolved separately, so the test exercises repository artifact-descriptor resolution rather than relying only on an in-reactor model.
Checklist
mvn verifyhas been run successfully.License