Avoid IllegalStateException on duplicate profile ids in DefaultModelBuilder#12419
Avoid IllegalStateException on duplicate profile ids in DefaultModelBuilder#12419mvanhorn wants to merge 1 commit into
Conversation
gnodet
left a comment
There was a problem hiding this comment.
Review Summary
This PR correctly fixes issue #10209 (MNG-8418) — a regression where Collectors.toMap() in getProfileActivations threw IllegalStateException when a POM contained profiles with duplicate IDs.
The fix replaces the id-keyed Map<String, Activation> with a positionally-indexed List<Activation>, which avoids the toMap collision while preserving the save/restore semantics. The approach is sound:
- Positional safety:
getProfileActivationsandinjectProfileActivationsrun back-to-back on the same model with no intervening profile-list mutations, so the positional correspondence is guaranteed. - Backwards compatibility:
DefaultModelValidatorcontinues to report duplicate profile IDs as a validation diagnostic. This PR removes the crash while preserving the warning — restoring Maven 3's behavior. - Test quality: The test directly exercises duplicate-ID profiles and verifies both activations survive the round-trip.
Minor suggestion
The new getProfileActivations includes all profiles via .map(Profile::getActivation), producing null entries for profiles without activations. This is functionally safe because injectProfileActivations guards access with if (activation != null), but the invariant is subtle. A brief comment (e.g., // null entries for profiles without activation; only accessed by index when activation is non-null) would make the contract explicit for future maintainers.
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
Summary
Projects with duplicate profile ids build again instead of dying with
java.lang.IllegalStateException: Duplicate key default (attempted merging values ...). Maven 3 accepted these POMs; Maven 4 rc-1/rc-2 crash during dependency collection.Why this matters
In #10209, @gnodet confirmed the exception is misleading: the activation save/restore map in model building is keyed by profile id, so the real condition is two
<profile>entries sharing an id (e.g. two<id>default</id>), surfacing as an opaque JDK collector error instead of a model diagnostic. @cstamas linked the regression to the MNG-8391 change. The issue is labeled bug/priority:major with no prior PRs.Changes
getProfileActivations/injectProfileActivationsinDefaultModelBuilderno longer key the activation save/restore by profile id - activations round-trip positionally withmodel.getProfiles(), so duplicate ids cannot collide in a map. This restores Maven 3's leniency in the model-building path whileDefaultModelValidatorremains the single owner of the duplicate-id diagnostic ("must be unique but found duplicate profile with id ..."), so no rawIllegalStateExceptionescapes to the user.Testing
mvn -pl impl/maven-impl -am test -Dtest=DefaultModelBuilderTest- 13 tests, 0 failures, including a new test withduplicate-profile-ids.xml(two profiles sharing an id, each with its own activation) verifying model building succeeds and both activations survive the save/restore round-trip.Fixes #10209