This is an automated email from the ASF dual-hosted git repository.
gnodet pushed a commit to branch maven-4.0.x
in repository https://gitbox.apache.org/repos/asf/maven.git
The following commit(s) were added to refs/heads/maven-4.0.x by this push:
new df4af8d8a6 model-builder: simplify subproject auto-discovery decision
(#11124) (#11132)
df4af8d8a6 is described below
commit df4af8d8a609308729fa8d151492db92d9eb0644
Author: Guillaume Nodet <[email protected]>
AuthorDate: Wed Sep 17 13:55:53 2025 +0200
model-builder: simplify subproject auto-discovery decision (#11124) (#11132)
- Treat explicit empty <subprojects/> as disabling discovery.
- Base decision solely on explicit subprojects/modules in the main model;
ignore profiles.
- Inline the check using location tracking and remove profile scanning.
(cherry picked from commit b2690b703ded7f369bf493418dbb4a040300f3c4)
---
.../project/DefaultMavenProjectBuilderTest.java | 40 ++++++++++++++++++++++
.../resources/projects/modules-empty/child/pom.xml | 8 +++++
.../test/resources/projects/modules-empty/pom.xml | 7 ++++
.../projects/subprojects-empty/child/pom.xml | 8 +++++
.../resources/projects/subprojects-empty/pom.xml | 7 ++++
.../maven/impl/model/DefaultModelBuilder.java | 16 ++++++++-
6 files changed, 85 insertions(+), 1 deletion(-)
diff --git
a/impl/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java
b/impl/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java
index 3c5bcdd0ac..13e766a957 100644
---
a/impl/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java
+++
b/impl/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java
@@ -545,4 +545,44 @@ public void testSubprojectDiscovery() throws Exception {
MavenProject parent = p1.getArtifactId().equals("parent") ? p1 : p2;
assertEquals(List.of("child"),
parent.getModel().getDelegate().getSubprojects());
}
+
+ @Test
+ public void testEmptySubprojectsElementPreventsDiscovery() throws
Exception {
+ File pom =
getTestFile("src/test/resources/projects/subprojects-empty/pom.xml");
+ ProjectBuildingRequest configuration = newBuildingRequest();
+ InternalSession internalSession =
InternalSession.from(configuration.getRepositorySession());
+ InternalMavenSession mavenSession =
InternalMavenSession.from(internalSession);
+ mavenSession
+ .getMavenSession()
+ .getRequest()
+ .setRootDirectory(pom.toPath().getParent());
+
+ List<ProjectBuildingResult> results =
projectBuilder.build(List.of(pom), true, configuration);
+ // Should only build the parent project, not discover the child
+ assertEquals(1, results.size());
+ MavenProject parent = results.get(0).getProject();
+ assertEquals("parent", parent.getArtifactId());
+ // The subprojects list should be empty since we explicitly defined an
empty <subprojects /> element
+ assertTrue(parent.getModel().getDelegate().getSubprojects().isEmpty());
+ }
+
+ @Test
+ public void testEmptyModulesElementPreventsDiscovery() throws Exception {
+ File pom =
getTestFile("src/test/resources/projects/modules-empty/pom.xml");
+ ProjectBuildingRequest configuration = newBuildingRequest();
+ InternalSession internalSession =
InternalSession.from(configuration.getRepositorySession());
+ InternalMavenSession mavenSession =
InternalMavenSession.from(internalSession);
+ mavenSession
+ .getMavenSession()
+ .getRequest()
+ .setRootDirectory(pom.toPath().getParent());
+
+ List<ProjectBuildingResult> results =
projectBuilder.build(List.of(pom), true, configuration);
+ // Should only build the parent project, not discover the child
+ assertEquals(1, results.size());
+ MavenProject parent = results.get(0).getProject();
+ assertEquals("parent", parent.getArtifactId());
+ // The modules list should be empty since we explicitly defined an
empty <modules /> element
+ assertTrue(parent.getModel().getDelegate().getModules().isEmpty());
+ }
}
diff --git
a/impl/maven-core/src/test/resources/projects/modules-empty/child/pom.xml
b/impl/maven-core/src/test/resources/projects/modules-empty/child/pom.xml
new file mode 100644
index 0000000000..022d865352
--- /dev/null
+++ b/impl/maven-core/src/test/resources/projects/modules-empty/child/pom.xml
@@ -0,0 +1,8 @@
+<project xmlns="http://maven.apache.org/POM/4.1.0">
+ <parent>
+ <groupId>modules-empty</groupId>
+ <artifactId>parent</artifactId>
+ </parent>
+ <artifactId>child</artifactId>
+ <packaging>jar</packaging>
+</project>
diff --git a/impl/maven-core/src/test/resources/projects/modules-empty/pom.xml
b/impl/maven-core/src/test/resources/projects/modules-empty/pom.xml
new file mode 100644
index 0000000000..b36128e6a5
--- /dev/null
+++ b/impl/maven-core/src/test/resources/projects/modules-empty/pom.xml
@@ -0,0 +1,7 @@
+<project xmlns="http://maven.apache.org/POM/4.1.0">
+ <groupId>modules-empty</groupId>
+ <artifactId>parent</artifactId>
+ <version>1</version>
+ <packaging>pom</packaging>
+ <modules />
+</project>
diff --git
a/impl/maven-core/src/test/resources/projects/subprojects-empty/child/pom.xml
b/impl/maven-core/src/test/resources/projects/subprojects-empty/child/pom.xml
new file mode 100644
index 0000000000..1c4f2b7709
--- /dev/null
+++
b/impl/maven-core/src/test/resources/projects/subprojects-empty/child/pom.xml
@@ -0,0 +1,8 @@
+<project xmlns="http://maven.apache.org/POM/4.1.0">
+ <parent>
+ <groupId>subprojects-empty</groupId>
+ <artifactId>parent</artifactId>
+ </parent>
+ <artifactId>child</artifactId>
+ <packaging>jar</packaging>
+</project>
diff --git
a/impl/maven-core/src/test/resources/projects/subprojects-empty/pom.xml
b/impl/maven-core/src/test/resources/projects/subprojects-empty/pom.xml
new file mode 100644
index 0000000000..840c572d1d
--- /dev/null
+++ b/impl/maven-core/src/test/resources/projects/subprojects-empty/pom.xml
@@ -0,0 +1,7 @@
+<project xmlns="http://maven.apache.org/POM/4.1.0">
+ <groupId>subprojects-empty</groupId>
+ <artifactId>parent</artifactId>
+ <version>1</version>
+ <packaging>pom</packaging>
+ <subprojects />
+</project>
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 e3091e3b6d..9ab2505871 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
@@ -1366,7 +1366,7 @@ Model doReadFileModel() throws ModelBuilderException {
}
// subprojects discovery
- if (getSubprojects(model).isEmpty()
+ if (!hasSubprojectsDefined(model)
// only discover subprojects if POM > 4.0.0
&& !MODEL_VERSION_4_0_0.equals(model.getModelVersion())
// and if packaging is POM (we check type, but the
session is not yet available,
@@ -1902,6 +1902,20 @@ private static List<String> getSubprojects(Model
activated) {
return subprojects;
}
+ /**
+ * Checks if subprojects are explicitly defined in the main model.
+ * This method distinguishes between:
+ * 1. No subprojects/modules element present - returns false (should
auto-discover)
+ * 2. Empty subprojects/modules element present - returns true (should NOT
auto-discover)
+ * 3. Non-empty subprojects/modules - returns true (should NOT
auto-discover)
+ */
+ @SuppressWarnings("deprecation")
+ private static boolean hasSubprojectsDefined(Model model) {
+ // Only consider the main model: profiles do not influence
auto-discovery
+ // Inline the check for explicit elements using location tracking
+ return model.getLocation("subprojects") != null ||
model.getLocation("modules") != null;
+ }
+
@Override
public Model buildRawModel(ModelBuilderRequest request) throws
ModelBuilderException {
RequestTraceHelper.ResolverTrace trace =
RequestTraceHelper.enter(request.getSession(), request);