Skip to content

[maven-4.0.x] Fix #12304: replace deprecated property expressions in mvnup - #12308

Merged
gnodet merged 1 commit into
maven-4.0.xfrom
fix-mvnup-deprecated-properties
Jun 18, 2026
Merged

gnodet merged 1 commit into
maven-4.0.xfrom
fix-mvnup-deprecated-properties

Conversation

@gnodet

@gnodet gnodet commented Jun 18, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds fixDeprecatedPropertyExpressions() to CompatibilityFixStrategy that replaces deprecated Maven 2/3 shorthand properties (${version}, ${groupId}, ${artifactId}) with their Maven 4-compatible ${project.*} equivalents.

  • Scans all text content in the POM (dependencies, plugin configs, properties, etc.) via recursive DOM traversal
  • Runs before the undefined-property check so replaced expressions are not falsely flagged as undefined
  • Adds 5 unit tests covering the new fix, including negative case (already-correct POMs unmodified)

The DefaultSourceRoot targetPath fix (#12306) has been split into a separate PR: #12311.

Fixes #12304

Test plan

  • Unit tests: CompatibilityFixStrategyTest — 5 new tests in DeprecatedPropertyExpressionFixesTests
  • Full module build passes

🤖 Generated with Claude Code

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates Maven’s mvnup compatibility fixer to rewrite deprecated prefixless Maven model expressions (${version}, ${groupId}, ${artifactId}) to their ${project.*} equivalents, and also adjusts DefaultSourceRoot to treat a normalized "." resource targetPath as absent.

Changes:

  • Add recursive DOM traversal in CompatibilityFixStrategy to replace deprecated shorthand expressions before undefined-property checks run.
  • Add unit tests covering the new deprecated-expression replacements in various POM locations.
  • Normalize DefaultSourceRoot resource targetPath so "." becomes “absent” and "./subdir" becomes "subdir", with new unit tests.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultSourceRoot.java Treats normalized empty targetPath (e.g., ".") as absent (null).
impl/maven-impl/src/test/java/org/apache/maven/impl/DefaultSourceRootTest.java Adds tests for "." and "./subdir" targetPath normalization behavior.
impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/CompatibilityFixStrategy.java Adds deprecated `${version
impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/CompatibilityFixStrategyTest.java Adds unit tests validating deprecated-expression replacements and a non-modification case.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +232 to +258
/** 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());
}
Comment on lines +763 to +800
/**
* Fixes deprecated Maven 2/3 shorthand property expressions throughout the POM.
* Replaces ${version}, ${groupId}, and ${artifactId} with their ${project.*} equivalents,
* which are the only forms supported in Maven 4.
*/
private boolean fixDeprecatedPropertyExpressions(Document pomDocument, UpgradeContext context) {
return fixDeprecatedPropertyExpressionsInElement(pomDocument.root(), context);
}

private boolean fixDeprecatedPropertyExpressionsInElement(Element element, UpgradeContext context) {
boolean fixed = false;

List<Element> children = element.childElements().toList();

if (children.isEmpty()) {
String text = element.textContent();
if (text != null && !text.isEmpty()) {
String fixedText = replaceDeprecatedExpressions(text);
if (!fixedText.equals(text)) {
element.textContent(fixedText);
context.detail("Fixed: replaced deprecated property expression in <" + element.name() + ">: "
+ text.trim() + " → " + fixedText.trim());
fixed = true;
}
}
} else {
for (Element child : children) {
fixed |= fixDeprecatedPropertyExpressionsInElement(child, context);
}
}

return fixed;
}

private static String replaceDeprecatedExpressions(String text) {
return text.replace("${version}", "${project.version}")
.replace("${groupId}", "${project.groupId}")
.replace("${artifactId}", "${project.artifactId}");
@gnodet gnodet changed the title Add deprecated property replacement (${version} → ${project.version}) to mvnup [maven-4.0.x] Fix #12304 and #12306: deprecated property expressions and targetPath normalization Jun 18, 2026
@gnodet gnodet added this to the 4.0.0-rc-6 milestone Jun 18, 2026
@gnodet gnodet added the bug Something isn't working label Jun 18, 2026
@gnodet gnodet self-assigned this Jun 18, 2026
… to mvnup

Maven 3 supported ${version}, ${groupId}, and ${artifactId} as shorthand
aliases for their ${project.*} equivalents. Maven 4 drops these deprecated
aliases (see #12304), causing builds to fail.

Add fixDeprecatedPropertyExpressions() to CompatibilityFixStrategy that
scans all text content in the POM and replaces the deprecated expressions
with their ${project.*} equivalents. This fix runs before the undefined
property expression check so that already-replaced expressions are not
falsely flagged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@gnodet
gnodet force-pushed the fix-mvnup-deprecated-properties branch from 26fd4f5 to 945f296 Compare June 18, 2026 11:51
@gnodet gnodet changed the title [maven-4.0.x] Fix #12304 and #12306: deprecated property expressions and targetPath normalization [maven-4.0.x] Fix #12304: replace deprecated property expressions in mvnup Jun 18, 2026
@gnodet
gnodet merged commit fe2a85a into maven-4.0.x Jun 18, 2026
23 checks passed
@gnodet
gnodet deleted the fix-mvnup-deprecated-properties branch June 18, 2026 13:05
gnodet added a commit that referenced this pull request Jun 18, 2026
… to mvnup (#12308) (#12313)

Maven 3 supported ${version}, ${groupId}, and ${artifactId} as shorthand
aliases for their ${project.*} equivalents. Maven 4 drops these deprecated
aliases (see #12304), causing builds to fail.

Add fixDeprecatedPropertyExpressions() to CompatibilityFixStrategy that
scans all text content in the POM and replaces the deprecated expressions
with their ${project.*} equivalents. This fix runs before the undefined
property expression check so that already-replaced expressions are not
falsely flagged.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants