You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by gn...@apache.org on 2026/09/02 06:55:08 UTC
(maven) 01/02: [MNG-8708] Fix Maven 4 parent inference
This is an automated email from the ASF dual-hosted git repository.
gnodet pushed a commit to branch backport/12703-to-maven-4.0.x
in repository https://gitbox.apache.org/repos/asf/maven.git
commit 02701fee2dfcbdc0d57982a604de159521077be0
Author: goutamadwant <wo...@gmail.com>
AuthorDate: Fri Aug 7 22:32:45 2026 -0700
[MNG-8708] Fix Maven 4 parent inference
Distinguish explicitly declared parent coordinates from values inferred through relativePath. Infer an omitted parent version from the matching reactor model before raw-model validation.
Signed-off-by: goutamadwant <wo...@gmail.com>
---
.../maven/impl/model/DefaultModelBuilder.java | 37 +++++++++++++-
.../maven/impl/model/DefaultModelValidator.java | 4 +-
.../it/MavenITmng8708ParentInferenceTest.java | 56 ++++++++++++++++++++++
.../explicit-both/modules/child/pom.xml | 10 ++++
.../explicit-both/pom.xml | 11 +++++
.../supported/modules/gav-only/pom.xml | 9 ++++
.../supported/modules/path-only/pom.xml | 8 ++++
.../mng-8708-parent-inference/supported/pom.xml | 12 +++++
8 files changed, 142 insertions(+), 5 deletions(-)
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 88d0c31b08..0a3caeae09 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
@@ -694,9 +694,11 @@ public void mergeRepositories(Model model, boolean replace) {
//
// Transform raw model to build pom.
- // Infer inner reactor dependencies version
+ // Infer missing coordinates from models in the reactor
//
Model transformFileToRaw(Model model) {
+ Parent newParent = inferParentVersion(model);
+
List<Dependency> newDeps = null;
boolean depsChanged = false;
if (!model.getDependencies().isEmpty()) {
@@ -712,10 +714,13 @@ Model transformFileToRaw(Model model) {
managedDepsChanged = inferDependencies(model, depMgmt.getDependencies(), newManagedDeps);
}
- if (!depsChanged && !managedDepsChanged) {
+ if (newParent == null && !depsChanged && !managedDepsChanged) {
return model;
}
Model.Builder builder = Model.newBuilder(model);
+ if (newParent != null) {
+ builder.parent(newParent);
+ }
if (depsChanged) {
builder.dependencies(newDeps);
}
@@ -725,6 +730,34 @@ Model transformFileToRaw(Model model) {
return builder.build();
}
+ private Parent inferParentVersion(Model model) {
+ Parent parent = model.getParent();
+ if (parent == null
+ || parent.getVersion() != null
+ || parent.getGroupId() == null
+ || parent.getArtifactId() == null) {
+ return null;
+ }
+
+ Model parentModel = getRawModel(model.getPomFile(), parent.getGroupId(), parent.getArtifactId());
+ if (parentModel == null) {
+ return null;
+ }
+
+ String version = parentModel.getVersion();
+ InputLocation versionLocation = parentModel.getLocation("version");
+ if (version == null && parentModel.getParent() != null) {
+ version = parentModel.getParent().getVersion();
+ versionLocation = parentModel.getParent().getLocation("version");
+ }
+ return version != null
+ ? parent.with()
+ .version(version)
+ .location("version", versionLocation)
+ .build()
+ : null;
+ }
+
/**
* 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}.
diff --git a/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelValidator.java b/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelValidator.java
index b1a805ce64..292c51b145 100644
--- a/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelValidator.java
+++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelValidator.java
@@ -339,9 +339,7 @@ public void validateFileModel(Session s, Model m, int validationLevel, ModelProb
if (parent.getRelativePath() != null
&& !parent.getRelativePath().isEmpty()
- && (parent.getGroupId() != null && !parent.getGroupId().isEmpty()
- || parent.getArtifactId() != null
- && !parent.getArtifactId().isEmpty())
+ && (parent.getLocation("groupId") != null || parent.getLocation("artifactId") != null)
&& validationLevel >= ModelValidator.VALIDATION_LEVEL_MAVEN_4_0
&& ModelBuilder.KNOWN_MODEL_VERSIONS.contains(m.getModelVersion())
&& !Objects.equals(m.getModelVersion(), ModelBuilder.MODEL_VERSION_4_0_0)) {
diff --git a/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng8708ParentInferenceTest.java b/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng8708ParentInferenceTest.java
new file mode 100644
index 0000000000..2a5c87da4b
--- /dev/null
+++ b/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng8708ParentInferenceTest.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.it;
+
+import java.nio.file.Path;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * This is a test set for <a href="https://issues.apache.org/jira/browse/MNG-8708">MNG-8708</a>.
+ *
+ * @since 4.1.0
+ */
+class MavenITmng8708ParentInferenceTest extends AbstractMavenIntegrationTestCase {
+
+ private static final String PARENT_DECLARATION_WARNING =
+ "'parent.relativePath' only specify relativePath or groupId/artifactId in modelVersion 4.1.0";
+
+ @Test
+ void testSupportedParentInference() throws Exception {
+ Path testDir = extractResources("mng-8708-parent-inference/supported");
+
+ Verifier verifier = newVerifier(testDir);
+ verifier.addCliArgument("validate");
+ verifier.execute();
+ verifier.verifyErrorFreeLog();
+ verifier.verifyTextNotInLog(PARENT_DECLARATION_WARNING);
+ }
+
+ @Test
+ void testExplicitPathAndCoordinatesStillWarn() throws Exception {
+ Path testDir = extractResources("mng-8708-parent-inference/explicit-both");
+
+ Verifier verifier = newVerifier(testDir);
+ verifier.addCliArgument("validate");
+ verifier.execute();
+ verifier.verifyErrorFreeLog();
+ verifier.verifyTextInLog(PARENT_DECLARATION_WARNING);
+ }
+}
diff --git a/its/core-it-suite/src/test/resources/mng-8708-parent-inference/explicit-both/modules/child/pom.xml b/its/core-it-suite/src/test/resources/mng-8708-parent-inference/explicit-both/modules/child/pom.xml
new file mode 100644
index 0000000000..3ca85d2e25
--- /dev/null
+++ b/its/core-it-suite/src/test/resources/mng-8708-parent-inference/explicit-both/modules/child/pom.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.1.0">
+ <parent>
+ <groupId>org.apache.maven.its.mng8708</groupId>
+ <artifactId>parent</artifactId>
+ <relativePath>../..</relativePath>
+ </parent>
+
+ <artifactId>child</artifactId>
+</project>
diff --git a/its/core-it-suite/src/test/resources/mng-8708-parent-inference/explicit-both/pom.xml b/its/core-it-suite/src/test/resources/mng-8708-parent-inference/explicit-both/pom.xml
new file mode 100644
index 0000000000..b9acadfb5d
--- /dev/null
+++ b/its/core-it-suite/src/test/resources/mng-8708-parent-inference/explicit-both/pom.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.1.0" root="true">
+ <groupId>org.apache.maven.its.mng8708</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <subprojects>
+ <subproject>modules/child</subproject>
+ </subprojects>
+</project>
diff --git a/its/core-it-suite/src/test/resources/mng-8708-parent-inference/supported/modules/gav-only/pom.xml b/its/core-it-suite/src/test/resources/mng-8708-parent-inference/supported/modules/gav-only/pom.xml
new file mode 100644
index 0000000000..2647321e95
--- /dev/null
+++ b/its/core-it-suite/src/test/resources/mng-8708-parent-inference/supported/modules/gav-only/pom.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.1.0">
+ <parent>
+ <groupId>org.apache.maven.its.mng8708</groupId>
+ <artifactId>parent</artifactId>
+ </parent>
+
+ <artifactId>gav-only</artifactId>
+</project>
diff --git a/its/core-it-suite/src/test/resources/mng-8708-parent-inference/supported/modules/path-only/pom.xml b/its/core-it-suite/src/test/resources/mng-8708-parent-inference/supported/modules/path-only/pom.xml
new file mode 100644
index 0000000000..8a9d79925e
--- /dev/null
+++ b/its/core-it-suite/src/test/resources/mng-8708-parent-inference/supported/modules/path-only/pom.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.1.0">
+ <parent>
+ <relativePath>../..</relativePath>
+ </parent>
+
+ <artifactId>path-only</artifactId>
+</project>
diff --git a/its/core-it-suite/src/test/resources/mng-8708-parent-inference/supported/pom.xml b/its/core-it-suite/src/test/resources/mng-8708-parent-inference/supported/pom.xml
new file mode 100644
index 0000000000..879efe076e
--- /dev/null
+++ b/its/core-it-suite/src/test/resources/mng-8708-parent-inference/supported/pom.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.1.0" root="true">
+ <groupId>org.apache.maven.its.mng8708</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <subprojects>
+ <subproject>modules/path-only</subproject>
+ <subproject>modules/gav-only</subproject>
+ </subprojects>
+</project>