Skip to content

Fix ToolchainPluginStrategy to detect inherited source levels from parent POMs - #12973

Open
gnodet wants to merge 2 commits into
masterfrom
fix/toolchain-plugin-inherited-source-level
Open

Fix ToolchainPluginStrategy to detect inherited source levels from parent POMs#12973
gnodet wants to merge 2 commits into
masterfrom
fix/toolchain-plugin-inherited-source-level

Conversation

@gnodet

@gnodet gnodet commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Share Maven 4 API Session across all strategy instances via DCL singleton, enabling the RequestCache to deduplicate effective model builds across PluginUpgradeStrategy, ToolchainPluginStrategy, and CompatibilityFixStrategy
  • Route buildEffectiveModel() through InternalSession.request() to leverage the RequestCache — identical ModelBuilderRequest objects (same POM path) return cached results
  • Add effective model fallback in ToolchainPluginStrategy: when the local POM XML has no --source/--release config, resolve the fully-inherited effective model to detect compiler settings from parent POMs (e.g. org.apache.sling:sling-parent setting --source 6)
  • 8 new tests for effective model source level detection (properties, plugin config, pluginManagement, precedence rules)

Problem

When a project inherits --source 6 from a remote parent POM, mvnup's ToolchainPluginStrategy said "No source level configured" and skipped adding the toolchains plugin. This caused Maven 4 build failures because:

  1. detectSourceLevel() only inspected the local POM XML DOM
  2. Inherited compiler configuration from parent POMs was invisible to the strategy

Test plan

  • All 28 ToolchainPluginStrategyTest tests pass
  • All 510 mvnup tests pass (1 pre-existing unrelated error in PluginUpgradeCliTest)
  • CI build passes

🤖 Generated with Claude Code

…rent POMs

When a project inherits --source/--release from a remote parent POM
(e.g. org.apache.sling:sling-parent setting --source 6), mvnup's
ToolchainPluginStrategy failed to detect it because detectSourceLevel()
only inspected the local POM XML DOM. This caused mvnup to skip adding
the toolchains plugin, leading to Maven 4 build failures.

Changes:
- Share the Maven 4 API Session across all strategy instances (DCL
  singleton) so the Session's RequestCache deduplicates effective model
  builds across PluginUpgradeStrategy, ToolchainPluginStrategy, and
  CompatibilityFixStrategy
- Route buildEffectiveModel() through InternalSession.request() to
  leverage the RequestCache
- Add effective model fallback in ToolchainPluginStrategy: when local
  POM has no source level, resolve the effective model to pick up
  inherited compiler configuration from parent POMs
- Add 8 new tests for effective model source level detection

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gnodet
gnodet force-pushed the fix/toolchain-plugin-inherited-source-level branch from 3a3c891 to aaca753 Compare August 31, 2026 13:41
Move the Maven 4 API Session creation from AbstractUpgradeStrategy
into a dedicated MvnupSessionHolder class that uses @provides
@singleton to produce the Session as a DI-managed bean. The DI
container calls createSession() once and injects the singleton
Session into all strategy instances via @Inject @nAmed("mvnup")
field injection on the abstract base class.

This replaces the manual DCL singleton pattern with proper DI
lifecycle management. A static fallback in getSession() preserves
backward compatibility for unit tests that instantiate strategies
directly (without DI).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gnodet
gnodet force-pushed the fix/toolchain-plugin-inherited-source-level branch from 9d704c2 to a3c0591 Compare August 31, 2026 18:05
@gnodet gnodet added this to the 4.0.0-rc-7 milestone Aug 31, 2026
@gnodet
gnodet marked this pull request as ready for review August 31, 2026 20:34

@gnodet gnodet left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Well-structured refactoring that correctly extracts session management into a DI-managed singleton, adds a proper DCL fallback for tests, and implements sound effective model source-level detection with good test coverage.

Observations (non-blocking):

  1. [low] detectFromEffectivePlugins() matches only on artifactId (ToolchainPluginStrategy.java ~line 346) — Unlike the XML-based detectFromPluginSection() which also validates groupId, the effective model path checks only artifactId. Safe in practice since Maven defaults the groupId to org.apache.maven.plugins, but it's an inconsistency between the two code paths.

  2. [low] Documentation accuracy (MvnupSessionHolder.java ~line 50) — The Javadoc states the shared session enables cache sharing across PluginUpgradeStrategy, ToolchainPluginStrategy, and CompatibilityFixStrategy. In practice, PluginUpgradeStrategy builds effective models from temporary POM paths while ToolchainPluginStrategy uses real POM paths, so cross-strategy deduplication won't actually occur between those two.

What looks good:

  • DCL pattern is textbook correct: volatile field, outer null check, synchronized block, inner null check
  • @Inject @Named("mvnup") / @Provides @Singleton @Named("mvnup") pairing avoids DI conflicts
  • RequestCache integration is sound — ModelBuilderRequest has proper equals()/hashCode() for cache key deduplication
  • Exception handling in detectSourceLevelFromEffectiveModel() correctly catches all exceptions and falls back to -1
  • 8 new tests cover property and plugin detection paths well, including precedence rules

This review was generated by an AI agent (Claude Code) and may contain inaccuracies. Please verify all suggestions before applying.

Claude Code on behalf of Guillaume Nodet

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant