gnodet commented on issue #12306:
URL: https://github.com/apache/maven/issues/12306#issuecomment-4738562108
## Root Cause Analysis: `<targetPath>.</targetPath>` → empty string →
absolute path at filesystem root
### The triggering config in `taglibs-rdc/pom.xml`
```xml
<resource>
<directory>src/main/resources</directory>
<targetPath>.</targetPath> <!-- a literal dot -->
</resource>
```
### The bug chain (Maven 4 only)
1. **`DefaultSourceRoot.java:111`** — constructor normalizes targetPath via
Java NIO:
```java
this.targetPathOrNull = (targetPathOrNull != null) ?
targetPathOrNull.normalize() : null;
```
`Path.of(".").normalize()` returns an **empty path** (zero name elements,
`toString()=""`) because `.` is a redundant element. The result is **not
null**, so it gets stored as a non-null empty Path.
2. **`ConnectedResource.java:46`** — converts it to an empty string for the
legacy plugin:
```java
.targetPath(sourceRoot.targetPath().map(Path::toString).orElse(null))
// → "" (empty string, NOT null)
```
3. **`DefaultMavenResourcesFiltering.getDestinationFile()`** — the plugin
concatenates:
```java
destination = "" + "/" +
"org/apache/taglibs/rdc/resources/RDCBundle_en_US.properties"
=
"/org/apache/taglibs/rdc/resources/RDCBundle_en_US.properties" // absolute!
```
Java's `File("/org/...").isAbsolute() == true`, so `outputDirectory`
(`/project/target/classes`) is **completely bypassed**. Maven tries to write to
the filesystem root → `NoSuchFileException`.
### Why Maven 3 worked
Maven 3 passed the original `"."` string to the plugin without NIO
normalization. The plugin computed `"." + "/" + filename = "./filename"`
(relative), which was correctly resolved against the output directory.
### Fix location
**`DefaultSourceRoot.java:111`** — treat empty normalized paths as null
(same semantics as no targetPath):
```java
if (targetPathOrNull != null) {
Path normalized = targetPathOrNull.normalize();
// "." normalizes to empty path = "copy to output root" = same as null
this.targetPathOrNull = (normalized.getNameCount() == 0) ? null :
normalized;
} else {
this.targetPathOrNull = null;
}
```
The existing test `testHandlesEmptyTargetPathFromResource` tests explicit
`""` (handled by `nonBlank()` → null, never reaches the normalization path),
but **there's no test for `"."` which takes a completely different code path**.
A test for `targetPath="."` would have caught this.
_Claude Code on behalf of Guillaume Nodet_
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]