ascheman opened a new issue, #12507:
URL: https://github.com/apache/maven/issues/12507
### Affected versions
Reproduced on **both** `master` (`4.1.0-SNAPSHOT`, 671031e6) and
`maven-4.0.x` tip (`4.0.0-SNAPSHOT`, e1f82346b2). On 4.0.0-rc-5 the symptom is
masked by the launcher bug #11978 (`eval` → `bad substitution`), already fixed
for rc-6 — this issue is about what happens once Maven actually runs.
### Reproduction
Minimal `pom`-packaging project, then (quoted so the shell passes `${...}`
literally):
```
mvn deploy
'-DaltDeploymentRepository=test::file://${project.build.directory}/deploy'
```
* **Maven 3.9.16** (deploy-plugin pinned to 3.1.3 via direct goal
invocation): resolves the expression, deploys to `target/deploy/…` ✅
* **Maven 4** (same deploy-plugin 3.1.3): the expression evaluates to the
**empty string** → repository URL becomes `file:///deploy` → `Could not
transfer artifact … from/to test (file:///deploy): /deploy: Read-only file
system` ❌
Further probes — all wiped to empty: `${project.build.directory}`,
`${project.basedir}`, and even `${user.dir}` (a plain system property).
### Analysis
The values are destroyed at **CLI parse time**, before any project context
exists:
* `BaseParser.populateUserProperties()` interpolates all user-specified `-D`
values against only the other user properties plus the small
`extraInterpolationSource()` paths map — no system properties, no project
context
(`impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/BaseParser.java:441`).
* It uses the `Interpolator.interpolate(Map, UnaryOperator)` convenience
overload, which defaults to `defaultsToEmpty = true`
(`api/maven-api-core/…/Interpolator.java:51-53`), so `DefaultInterpolator`
replaces every unresolvable placeholder with `""`
(`impl/maven-impl/…/model/DefaultInterpolator.java:351-353`).
* The later v3-compat `PluginParameterExpressionEvaluator` would resolve
these expressions fine (it merges user + system properties and recursively
evaluates embedded `${...}`), but it only ever sees the already-emptied value.
This is **independent of** (and complementary to) the recent launcher
quoting fixes: #11978/#11983 fixed the shell layer so `${...}` arguments arrive
intact in the JVM — the failing IT below passes arguments programmatically via
the Verifier (no shell involved) and still shows the wipe. Notably, on rc-5 the
launcher bug masked this issue with a loud `bad substitution` shell error; with
the launcher fix shipping in rc-6, users will instead hit this silent
empty-substitution first.
The parse-time interpolation itself was introduced deliberately by #2480
("User properties are not interpolated for paths") to support
`${session.topDirectory}`/`${session.rootDirectory}` in `-D` values — the
regression is the destructive `defaultsToEmpty=true` for every *other*
expression, and the asymmetry with the options interpolation (which does
include `systemProperties::get` in its callback chain,
`BaseParser.java:178-184`).
A minimal fix candidate: pass `defaultsToEmpty=false` for user-specified
properties (leaving unresolved placeholders literal for later mojo-parameter
evaluation), possibly plus `systemProperties::get` in the callback chain. Happy
to turn that into a PR.
### Impact
A common CI pattern (file-based staging deploy via
`altDeploymentRepository`) breaks, and the failure mode is nasty: no error,
Maven silently targets a wrong absolute path (`/deploy`). maven-assembly-plugin
already had to work around this in its ITs (apache/maven-assembly-plugin#1325).
Any `-D`-supplied plugin parameter whose value embeds `${...}` is affected, not
just deploy.
### Test coverage
No existing core IT covers this. I have a **failing IT ready to contribute**
(two cases: `${user.dir}` and `${project.build.directory}` in a CLI-supplied
parameter, asserting Maven 3 semantics via `maven-it-plugin-configuration`); it
fails on current master with `expected: <PRE-…-POST> but was: <PRE--POST>`. PR
follows.
cc @gnodet — given the launcher fix lands in rc-6, this becomes the first
user-visible failure mode for the `${...}`-in-`-D` pattern there.
--
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]