From 88d270ed4739ede352ef1484d0fd658cacad5242 Mon Sep 17 00:00:00 2001 From: Hiteshsai007 <172893304+Hiteshsai007@users.noreply.github.com> Date: Mon, 27 Jul 2026 14:36:34 +0000 Subject: [PATCH] Fix BOM version resolution for sibling modules in dependencyManagement transformFileToRaw() only processed model.getDependencies() and ignored model.getDependencyManagement().getDependencies(). As a result, a BOM subproject that lists sibling reactor modules in without a ended up with those versions missing from the raw and consumer POM. Extend the version/groupId inference to managed dependencies by extracting the shared loop into an inferDependencies() helper, and track the regular and managed dependency changes separately so the dependency list is only rebuilt when it actually changed. Rebased onto master so the diff only contains the functional change: the previous revision carried ~47 unrelated reformatting hunks in DefaultModelBuilder.java, re-indented DefaultModelBuilderTest.java to 8 spaces and dropped testDuplicateProfileIdsRetainActivations. Fixes https://github.com/apache/maven/issues/11147 Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com> --- .../maven/impl/model/DefaultModelBuilder.java | 53 +++++++++++++++---- .../impl/model/DefaultModelBuilderTest.java | 48 +++++++++++++++++ .../poms/factory/bom-dep-mgmt-bom.xml | 36 +++++++++++++ .../poms/factory/bom-dep-mgmt-lib.xml | 25 +++++++++ .../poms/factory/bom-dep-mgmt-parent.xml | 23 ++++++++ 5 files changed, 174 insertions(+), 11 deletions(-) create mode 100644 impl/maven-impl/src/test/resources/poms/factory/bom-dep-mgmt-bom.xml create mode 100644 impl/maven-impl/src/test/resources/poms/factory/bom-dep-mgmt-lib.xml create mode 100644 impl/maven-impl/src/test/resources/poms/factory/bom-dep-mgmt-parent.xml diff --git a/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java b/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java index 182d0f1ae811..7de27dfe567d 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java @@ -611,28 +611,59 @@ public void mergeRepositories(Model model, boolean replace) { // Infer inner reactor dependencies version // Model transformFileToRaw(Model model) { - if (model.getDependencies().isEmpty()) { + List newDeps = null; + boolean depsChanged = false; + if (!model.getDependencies().isEmpty()) { + newDeps = new ArrayList<>(model.getDependencies().size()); + depsChanged = inferDependencies(model, model.getDependencies(), newDeps); + } + + DependencyManagement depMgmt = model.getDependencyManagement(); + List newManagedDeps = null; + boolean managedDepsChanged = false; + if (depMgmt != null && !depMgmt.getDependencies().isEmpty()) { + newManagedDeps = new ArrayList<>(depMgmt.getDependencies().size()); + managedDepsChanged = inferDependencies(model, depMgmt.getDependencies(), newManagedDeps); + } + + if (!depsChanged && !managedDepsChanged) { return model; } - List newDeps = new ArrayList<>(model.getDependencies().size()); + Model.Builder builder = Model.newBuilder(model); + if (depsChanged) { + builder.dependencies(newDeps); + } + if (managedDepsChanged) { + builder.dependencyManagement(depMgmt.withDependencies(newManagedDeps)); + } + return builder.build(); + } + + /** + * Infers the missing version or groupId of the given dependencies by looking them up in the reactor. + * Each dependency, either the original one or the inferred one, is added to {@code result}. + * + * @param model the model declaring the dependencies + * @param dependencies the dependencies to process + * @param result the list collecting the resulting dependencies + * @return whether at least one dependency has been inferred + */ + private boolean inferDependencies(Model model, List dependencies, List result) { boolean changed = false; - for (Dependency dep : model.getDependencies()) { + for (Dependency dep : dependencies) { Dependency newDep = null; if (dep.getVersion() == null) { newDep = inferDependencyVersion(model, dep); - if (newDep != null) { - changed = true; - } } else if (dep.getGroupId() == null) { // Handle missing groupId when version is present newDep = inferDependencyGroupId(model, dep); - if (newDep != null) { - changed = true; - } } - newDeps.add(newDep == null ? dep : newDep); + if (newDep != null) { + changed = true; + } + result.add(newDep == null ? dep : newDep); } - return changed ? model.withDependencies(newDeps) : model; + return changed; } private Dependency inferDependencyVersion(Model model, Dependency dep) { diff --git a/impl/maven-impl/src/test/java/org/apache/maven/impl/model/DefaultModelBuilderTest.java b/impl/maven-impl/src/test/java/org/apache/maven/impl/model/DefaultModelBuilderTest.java index 0789ca89fa90..f013d4c22429 100644 --- a/impl/maven-impl/src/test/java/org/apache/maven/impl/model/DefaultModelBuilderTest.java +++ b/impl/maven-impl/src/test/java/org/apache/maven/impl/model/DefaultModelBuilderTest.java @@ -28,6 +28,7 @@ import org.apache.maven.api.RemoteRepository; import org.apache.maven.api.Session; import org.apache.maven.api.model.Dependency; +import org.apache.maven.api.model.DependencyManagement; import org.apache.maven.api.model.Model; import org.apache.maven.api.model.Repository; import org.apache.maven.api.services.ModelBuilder; @@ -444,6 +445,53 @@ public void testBuildConsumerResolvesParentProfileProperties() { "Managed dependency version should be interpolated, not ${managed.version}"); } + /** + * Verifies that the versions of sibling reactor modules declared in {@code } + * are inferred, just like they already are for regular dependencies (GH-11147). + * This is the typical BOM use case where a subproject lists its siblings without their versions. + */ + @Test + public void testBomDependencyManagementVersionInference() { + // Build the lib POM first: this creates the main session and registers the sibling module + ModelBuilder.ModelBuilderSession mbs = builder.newSession(); + mbs.build(ModelBuilderRequest.builder() + .session(session) + .requestType(ModelBuilderRequest.RequestType.BUILD_PROJECT) + .source(Sources.buildSource(getPom("bom-dep-mgmt-lib"))) + .build()); + + // Access the main session (package-private) to invoke the file to raw model transformation + DefaultModelBuilder.ModelBuilderSessionState mainState = + ((DefaultModelBuilder.ModelBuilderSessionImpl) mbs).mainSession; + + // A BOM declaring a sibling module in dependencyManagement, without a version + Model bomModel = Model.newBuilder() + .modelVersion("4.1.0") + .groupId("org.apache.maven.tests") + .artifactId("bom-dep-mgmt-bom") + .version("1.0-SNAPSHOT") + .packaging("pom") + .pomFile(getPom("bom-dep-mgmt-bom")) + .dependencyManagement(DependencyManagement.newBuilder() + .dependencies(List.of(Dependency.newBuilder() + .groupId("org.apache.maven.tests") + .artifactId("bom-dep-mgmt-lib") + .build())) + .build()) + .build(); + + Model transformed = mainState.transformFileToRaw(bomModel); + + assertNotNull(transformed.getDependencyManagement()); + Dependency managedDep = transformed.getDependencyManagement().getDependencies().stream() + .filter(d -> "bom-dep-mgmt-lib".equals(d.getArtifactId())) + .findFirst() + .orElse(null); + assertNotNull(managedDep, "Managed dependency for the sibling module should be kept"); + assertEquals( + "1.0-SNAPSHOT", managedDep.getVersion(), "Version should be inferred from the reactor sibling module"); + } + private Path getPom(String name) { return Paths.get("src/test/resources/poms/factory/" + name + ".xml").toAbsolutePath(); } diff --git a/impl/maven-impl/src/test/resources/poms/factory/bom-dep-mgmt-bom.xml b/impl/maven-impl/src/test/resources/poms/factory/bom-dep-mgmt-bom.xml new file mode 100644 index 000000000000..8d90fef50283 --- /dev/null +++ b/impl/maven-impl/src/test/resources/poms/factory/bom-dep-mgmt-bom.xml @@ -0,0 +1,36 @@ + + + + + org.apache.maven.tests + bom-dep-mgmt-parent + bom-dep-mgmt-parent.xml + + bom-dep-mgmt-bom + pom + + + + + org.apache.maven.tests + bom-dep-mgmt-lib + + + + + diff --git a/impl/maven-impl/src/test/resources/poms/factory/bom-dep-mgmt-lib.xml b/impl/maven-impl/src/test/resources/poms/factory/bom-dep-mgmt-lib.xml new file mode 100644 index 000000000000..6034f67bd422 --- /dev/null +++ b/impl/maven-impl/src/test/resources/poms/factory/bom-dep-mgmt-lib.xml @@ -0,0 +1,25 @@ + + + + + org.apache.maven.tests + bom-dep-mgmt-parent + bom-dep-mgmt-parent.xml + + bom-dep-mgmt-lib + diff --git a/impl/maven-impl/src/test/resources/poms/factory/bom-dep-mgmt-parent.xml b/impl/maven-impl/src/test/resources/poms/factory/bom-dep-mgmt-parent.xml new file mode 100644 index 000000000000..2fb8117371a7 --- /dev/null +++ b/impl/maven-impl/src/test/resources/poms/factory/bom-dep-mgmt-parent.xml @@ -0,0 +1,23 @@ + + + + org.apache.maven.tests + bom-dep-mgmt-parent + 1.0-SNAPSHOT + pom +