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]

Reply via email to