This is an automated email from the ASF dual-hosted git repository. gnodet pushed a commit to branch fix-gh12306 in repository https://gitbox.apache.org/repos/asf/maven.git
commit af2aae8dcabad2ad02c9a8e402e028309bd729c1 Author: Guillaume Nodet <[email protected]> AuthorDate: Thu Jun 18 06:37:56 2026 +0000 Fix NoSuchFileException when resource targetPath is "." (#12306) `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 <[email protected]> --- .../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() {
