[MNG-8432] Inherit properties from imported BOMs#12417
Conversation
elharo
left a comment
There was a problem hiding this comment.
I'm not yet convinced this is a feature we want. It could have unforeseen consequences. care is warranted.
|
@elharo Thank you for the review. That is a very fair point, and I completely understand the hesitation. Changing the semantics of BOM imports to include To provide some context on the motivation: this was implemented to address MNG-8432 / #10196. It's a frequent pain point for users (as seen in this StackOverflow thread with 10k+ views). Currently, if a project imports a BOM to manage dependency versions, but needs to use one of those versions for a plugin configuration (like To mitigate the "unforeseen consequences", I've implemented a safeguard in this PR:
However, I understand there are still risks (e.g., conflicting properties if multiple BOMs are imported). How would you prefer to handle this design decision? A few potential options:
I'm happy to take this in whatever direction the core team feels is safest. |
gnodet
left a comment
There was a problem hiding this comment.
Review Summary
This PR modifies DefaultModelBuilder to inherit properties from imported BOMs and adds a second interpolateModel() pass to resolve them. While the feature request (MNG-8432) is legitimate and commonly requested, the implementation has several significant issues — including a confirmed CI failure.
Critical Issues
1. Double interpolation breaks property escaping (CI failure)
The second interpolateModel() call after importDependencyManagement() causes double interpolation. The first pass correctly turns \${test.value} into the literal ${test.value}. The second pass then erroneously resolves it. CI confirms: MavenITmng3558PropertyEscapingTest fails across all 9 matrix entries with:
expected: <${test.value}> but was: <interpolated-value>
2. Semantic change to BOM import scope
Maven's <scope>import</scope> in <dependencyManagement> is specified to import only the dependency management section, not properties. This is by design — property inheritance is the role of parent POMs. Changing this default behavior would affect every project that imports a BOM. As @elharo noted, this warrants a design discussion on dev@maven.apache.org before proceeding.
Major Issues
3. Fragile ordering dependency with multiple BOMs
The putIfAbsent semantics mean the first-declared BOM's properties win for any key. This creates an implicit ordering dependency that could cause hard-to-diagnose issues when BOMs define common properties (e.g., spring.version). No warning is produced on conflicts.
4. Unfiltered property import
All BOM properties are imported — including internal build properties like maven.compiler.source, project.build.sourceEncoding, plugin versions, etc. A typical Spring Boot or Quarkus BOM defines hundreds of properties, many not meant for export. This would pollute the consuming project's property space.
5. No new tests
A change of this significance should include tests for: basic property import, property precedence (local > BOM), multiple BOM ordering, interaction with property escaping, and interaction with parent inheritance.
Minor
6. The inner method doLoadDependencyManagement should be renamed to doLoadBomModel for consistency with the outer method rename.
Recommendation
If this feature is to be pursued, it likely needs:
- Community consensus via
dev@maven.apache.org(as @elharo suggested) - An opt-in mechanism rather than changing default behavior
- Integration of BOM properties before the first interpolation pass, not a second pass
- Comprehensive test coverage
This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.
Claude Code on behalf of Guillaume Nodet
Reviewed 3 PRs: - apache#12419: APPROVE (duplicate profile id fix) - apache#11770: COMMENT (regex bug, reinforces prior feedback) - apache#12417: COMMENT (CI failure, design concerns) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Address review feedback: - Fix double interpolation (CI failure): move BOM property merging BEFORE the first interpolation pass instead of adding a second interpolateModel() call - Make feature opt-in via maven.bom.import.properties user property (default: false) to avoid changing BOM import semantics for all projects - Add conflict warnings when multiple BOMs define the same property key with different values - Rename doLoadDependencyManagement -> doLoadBomModel for consistency - Revert loadBomModel back to loadDependencyManagement (returns DependencyManagement, not full Model) since importDependencyManagement no longer needs BOM properties
03ea6bb to
a0cb8d8
Compare
|
Thanks for the thorough review @gnodet — all points addressed in the latest force-push: 1. Double interpolation fix (CI failure): 2. Opt-in mechanism (semantic change): 3. Conflict warnings for multiple BOMs: 4. No unfiltered property pollution: 5. Tests: 6. Method rename: I agree that broader community discussion on |
gnodet
left a comment
There was a problem hiding this comment.
Re-review — New Commits
The double-interpolation issue from the previous review is correctly fixed — BOM properties are now imported before interpolation in readEffectiveModel(), eliminating the second interpolateModel() call. The opt-in mechanism via maven.bom.import.properties user property with @Config annotation is a sound design choice that preserves backward compatibility. The method rename from doLoadDependencyManagement → doLoadBomModel is a sensible improvement.
Findings
🔴 High — BOM filter condition skips type=bom dependencies
DefaultModelBuilder.java — The filter condition in importBomProperties:
if (!("pom".equals(dependency.getType()) && "import".equals(dependency.getScope()))
|| "bom".equals(dependency.getType())) {
continue;
}Due to operator precedence, this parses as (!A) || B — when type=bom, the expression evaluates to true, causing type=bom BOMs to be skipped. In Maven 4, type=bom is a valid BOM type (Type.BOM). This is a pre-existing pattern copied from importDependencyManagement, but since this is new code, it should be correct from the start. Consider: if (!(("pom".equals(type) && "import".equals(scope)) || "bom".equals(type))).
🔴 High — No tests added
The PR adds 100+ lines of new feature logic (BOM property import, conflict warnings, opt-in flag) but zero test files. At minimum, tests should verify: (1) feature is off by default, (2) when enabled, BOM properties are imported, (3) project properties take precedence over BOM properties, (4) first-declared BOM wins for conflicts.
🟡 Medium — No CI checks have run
No CI checks are reported on the mng-8432-bom-properties-in-child branch. The double-interpolation fix cannot be verified without CI passing.
🔵 Low — Unrelated cosmetic change
A blank line was removed between importMgmts = new ArrayList<>() and importMgmts.add(importMgmt) in the existing importDependencyManagement method. This is noise in the diff — consider reverting or submitting separately.
Summary
The architecture of this revision is much improved. Moving property import before interpolation is the correct approach, and the opt-in mechanism is well-designed. The main blockers are the absence of tests and the untested CI status. The BOM filter condition should also be fixed since this is new code.
This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.
Claude Code on behalf of Guillaume Nodet
Re-reviewed PRs apache#12419, apache#12417, apache#12416 after new commits. - apache#12419: APPROVE (formatting fix only) - apache#12417: COMMENT (improved but still no tests, BOM filter bug) - apache#12416: APPROVE (prior concerns addressed) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Re-review — New CommitsThe double-interpolation issue from the previous review is correctly fixed — BOM properties are now imported before interpolation in Addressed Findings🟢 Fixed — BOM filter condition skips 🟢 Fixed — Unnecessary blank line removed 🟢 Fixed — Unit tests for opt-in behavior and precedence
These tests handle Maven API model resolution properly by programmatic installation of the BOM artifacts into the test session's local repository ( ConclusionThe changes successfully fulfill the feature request for opt-in BOM property inheritance while remaining robust against edge cases. The newly introduced integration and unit tests are comprehensive and pass consistently. |
|
Thanks for working on this @Hiteshsai007. The pain point is real and well-documented (the SO thread has 10k+ views), so I understand the motivation. However, I don't think extending BOM imports to include properties is the right approach. Here are the concerns: Property pollutionA typical BOM (Spring Boot, Quarkus) defines hundreds of properties — Silent semantic driftEven with opt-in, enabling this once means every BOM import in the project starts leaking properties. Adding or removing a BOM — or reordering BOM declarations — becomes a much riskier operation, as it can silently change compiler settings, plugin versions, encoding, etc. Multi-BOM ordering fragilityWith multiple BOMs, property conflicts are resolved by declaration order (first wins). Reordering Blurs the parent/BOM distinctionMaven's model has a clear separation: parents provide inheritance (properties, plugins, settings), BOMs provide dependency management. This erodes that boundary. Mixins as the proper solutionMaven 4 already has mixins (4.2.0+) which are designed for exactly this use case. They already:
The scenario from MNG-8432 would be solved cleanly with: <mixins>
<mixin>
<groupId>com.company</groupId>
<artifactId>company-bom</artifactId>
<version>1.0.0</version>
</mixin>
</mixins>This gives both the dependency management and the properties, without silently pulling in properties from every BOM in the dependency management section. I think the right path forward is to point users toward mixins rather than overloading |
|
Thanks for the review and guidance, @gnodet! I agree that Following your suggestion, I have created a new pull request (#12461) which adds a dedicated integration test demonstrating how users can leverage |
|
Closing this PR — thanks for the effort @Hiteshsai007, and the pain point is well understood. After review, we've concluded that extending Maven 4 already provides mixins (4.2.0+) as the proper mechanism for this use case. Mixins give you explicit, selective inheritance of properties (and the full model) with clear semantics — without overloading BOM import behavior: <mixins>
<mixin>
<groupId>com.company</groupId>
<artifactId>company-bom</artifactId>
<version>1.0.0</version>
</mixin>
</mixins>See the earlier review comment for the full analysis. If you're interested in continuing to contribute, improving mixin documentation or integration test coverage would be very welcome. |
[MNG-8432] Inherit properties from imported BOMs
fixes #10196
Description
This PR resolves MNG-8432 (also referenced as #10196 on GitHub), which adds the capability to inherit properties from imported BOMs.
Previously, when a child project imported a BOM using
<dependencyManagement>with<scope>import</scope>, Maven only extracted and merged the<dependencyManagement>sections. The<properties>block of the BOM was entirely ignored. This limitation forced users to manually duplicate property definitions (e.g., version placeholders) in their consuming POMs to use them in plugins or standard dependencies.Changes in this PR:
DefaultModelBuilder.loadBomModelto fetch and return the complete resolvedModelof the BOM rather than just theDependencyManagementobject.importDependencyManagementto collect the properties from all imported BOM models and merge them into the consuming model. The consuming model's existing properties take precedence, preventing unwanted overrides.importDependencyManagementruns after the initial model interpolation pass (readEffectiveModel), added a second pass ofinterpolateModel(resultModel, request, this)immediately after importing the properties. This correctly substitutes BOM properties into the unresolved placeholders (e.g.,<version>${lib.version}</version>) within the model.Checklist