-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Description
Affected version
4.0.0-rc5, probably caused by #11370 in 4.0.0-rc5
Summary
When a project is built with Maven 4 using model version 4.1.0, the consumer POM transformation successfully downgrades child artifact POMs (jars, etc.) to model version 4.0.0. However, parent POMs (POM-packaged projects) by design remain at model version 4.1.0 in their consumer POM, because the transformation only strips some 4.1.0 features (root, subprojects, preserveModelVersion) but not others (condition/packaging in profile activation, extension configuration, build sources).
But since child artifact consumer POMs retain a <parent> reference (with only relativePath removed), Maven 3 and Gradle resolve the parent POM, encounter model version 4.1.0, and fail.
Reproduction / Example
This is happening in the wild with JLine 4.0.0, which was built with Maven 4 using model version 4.1.0:
- The child artifact POMs (e.g.,
jline-reader-4.0.0.pom) are correctly transformed to model version 4.0.0 - But they reference
org.jline:jline-parent:4.0.0as their parent - The parent POM
jline-parent-4.0.0.pomhas<modelVersion>4.1.0</modelVersion> - Maven 3 and Gradle cannot parse model version 4.1.0 and fail
See: jline/jline3#1688
Impact
This is a critical compatibility issue. Any project built with Maven 4 that uses model version 4.1.0 features in its parent POM chain will produce artifacts that cannot be consumed by:
- Maven 3
- Gradle (all versions)
- Any other tool that only supports model version 4.0.0
This effectively breaks the backwards compatibility promise of Maven 4's consumer POM mechanism.
Analysis
The consumer POM transformation in DefaultConsumerPomBuilder.transformPom() does the following for POM-packaged projects:
- Strips
root,modules,subprojects✓ - Strips
preserveModelVersion✓ - Strips
relativePathfrom parent ✓ - Computes the minimum model version via
MavenModelVersion.getModelVersion()✓
But several 4.1.0 features are not stripped, causing the model version to remain 4.1.0:
- Profile activation
condition - Profile activation
packaging - Extension
configuration - Build
sources(only conditionally stripped)
Even if all these were stripped, the problem is recursive: the parent POM's own parent may also be 4.1.0, and so on up the chain. The fundamental issue is that the consumer POM of a POM-packaged project retains the <parent> reference, and there is no guarantee that the entire parent chain is 4.0.0-compatible.