This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven.git


The following commit(s) were added to refs/heads/master by this push:
     new b2690b703d model-builder: simplify subproject auto-discovery decision 
(#11124)
b2690b703d is described below

commit b2690b703ded7f369bf493418dbb4a040300f3c4
Author: Guillaume Nodet <[email protected]>
AuthorDate: Wed Sep 17 12:48:19 2025 +0200

    model-builder: simplify subproject auto-discovery decision (#11124)
    
    - 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.
---
 .../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 b891b66d0a..27060c91dd 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
@@ -547,4 +547,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 95b7fd842a..9b17dcb380 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
@@ -1393,7 +1393,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,
@@ -1934,6 +1934,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);

Reply via email to