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/06/18 12:20:08 UTC

(maven) branch maven-4.0.x updated: Fix NoSuchFileException when resource targetPath is "." (#12306) (#12307)

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 19cdb5eb5e Fix NoSuchFileException when resource targetPath is "." (#12306) (#12307)
19cdb5eb5e is described below

commit 19cdb5eb5e328f1383e820152801998eadab0b54
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Thu Jun 18 14:20:02 2026 +0200

    Fix NoSuchFileException when resource targetPath is "." (#12306) (#12307)
    
    `Path.of(".").normalize()` returns a path whose `toString()` is empty
    but `getNameCount()` is 1, which was subsequently passed to plugins as
    an empty string, causing the plugin to construct an absolute path
    (`/org/apache/...`) and a NoSuchFileException.
    
    Treat any targetPath that normalizes to an empty string the same as a
    null (absent) targetPath.
    
    Co-authored-by: Claude Sonnet 4.6 <no...@anthropic.com>
---
 .../org/apache/maven/impl/DefaultSourceRoot.java   |  7 +++++-
 .../apache/maven/impl/DefaultSourceRootTest.java   | 28 ++++++++++++++++++++++
 2 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultSourceRoot.java b/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultSourceRoot.java
index d2b0142cfc..feadb91f6c 100644
--- a/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultSourceRoot.java
+++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultSourceRoot.java
@@ -108,7 +108,12 @@ public DefaultSourceRoot(
         this.includes = (includes != null) ? List.copyOf(includes) : List.of();
         this.excludes = (excludes != null) ? List.copyOf(excludes) : List.of();
         this.stringFiltering = stringFiltering;
-        this.targetPathOrNull = (targetPathOrNull != null) ? targetPathOrNull.normalize() : null;
+        if (targetPathOrNull != null) {
+            Path normalized = targetPathOrNull.normalize();
+            this.targetPathOrNull = normalized.toString().isEmpty() ? null : normalized;
+        } else {
+            this.targetPathOrNull = null;
+        }
         this.enabled = enabled;
     }
 
diff --git a/impl/maven-impl/src/test/java/org/apache/maven/impl/DefaultSourceRootTest.java b/impl/maven-impl/src/test/java/org/apache/maven/impl/DefaultSourceRootTest.java
index b74b5917bd..3f43d15af6 100644
--- a/impl/maven-impl/src/test/java/org/apache/maven/impl/DefaultSourceRootTest.java
+++ b/impl/maven-impl/src/test/java/org/apache/maven/impl/DefaultSourceRootTest.java
@@ -229,6 +229,34 @@ void testHandlesEmptyTargetPathFromResource() {
         assertFalse(targetPath.isPresent(), "targetPath should be empty for empty string");
     }
 
+    /** GH-12306: {@code targetPath="."} normalizes to an empty path and must be treated as absent. */
+    @Test
+    void testHandlesDotTargetPathFromResource() {
+        Resource resource = Resource.newBuilder()
+                .directory("src/main/resources")
+                .targetPath(".")
+                .build();
+
+        DefaultSourceRoot sourceRoot = new DefaultSourceRoot(Path.of("myproject"), ProjectScope.MAIN, resource);
+
+        assertFalse(sourceRoot.targetPath().isPresent(), "targetPath \".\" should be treated as absent");
+    }
+
+    /** GH-12306: {@code targetPath="./subdir"} normalizes to {@code "subdir"} and must be preserved. */
+    @Test
+    void testHandlesDotRelativeTargetPathFromResource() {
+        Resource resource = Resource.newBuilder()
+                .directory("src/main/resources")
+                .targetPath("./subdir")
+                .build();
+
+        DefaultSourceRoot sourceRoot = new DefaultSourceRoot(Path.of("myproject"), ProjectScope.MAIN, resource);
+
+        assertTrue(
+                sourceRoot.targetPath().isPresent(), "targetPath \"./subdir\" should be present after normalization");
+        assertEquals(Path.of("subdir"), sourceRoot.targetPath().orElseThrow());
+    }
+
     /*MNG-11062*/
     @Test
     void testHandlesPropertyPlaceholderInTargetPath() {