gnodet commented on issue #12522:
URL: https://github.com/apache/maven/issues/12522#issuecomment-5067602581
## Root Cause Analysis
The issue title says "extensions are picked up from non-extension marked
plugins," and indeed `DefaultMavenPluginManager.discoverPluginComponents()`
calls `container.discoverComponents(pluginRealm, ...)` for **all** plugins —
not just those with `<extensions>true</extensions>`. This registers every
`@Named` JSR 330 component from the plugin realm into Sisu's global
`BeanLocator`, including components like Tycho's `BndProjectExecutionListener`
that were never intended to act as Maven extensions.
However, this leak has existed since Maven 3 — the `discoverComponents` call
path is identical in Maven 3.9.x. The reason it didn't cause failures in Maven
3 is a change in how the listener list is consumed.
### Maven 3 — Plexus `@Requirement` (snapshot)
In Maven 3, `LifecycleModuleBuilder` uses Plexus annotations:
```java
@Requirement
private List<ProjectExecutionListener> projectExecutionListeners;
```
Plexus `@Requirement` on a `List<T>` resolves to a **snapshot** — a one-time
lookup populated at injection time. At that point no plugin realms have been
set up, so the list contains only core listeners. When `discoverComponents`
later registers Tycho's `BndProjectExecutionListener`, the snapshot doesn't
change and the problematic component is never iterated.
### Maven 4 — JSR 330 `@Inject` (live list)
MNG-5577 converted `LifecycleModuleBuilder` to JSR 330:
```java
@Inject
public LifecycleModuleBuilder(
...
List<ProjectExecutionListener> listeners,
...)
```
Sisu's `@Inject List<T>` produces a **live list** backed by `BeanLocator`.
When `discoverComponents` registers Tycho's listener, it dynamically appears in
the already-injected list. `CompoundProjectExecutionListener` then iterates it,
Sisu lazily provisions `BndProjectExecutionListener`, and provisioning fails
because its Tycho-internal dependency (`MavenReactorRepository`) isn't bound in
Maven's container.
### Fix in PR #12528
The PR adds a defensive iterator in
`CompoundProjectExecutionListener.safeListeners()` that catches
`RuntimeException` (Guice `ProvisionException`) during lazy provisioning and
skips unprovisionable listeners with a debug log, instead of aborting the build.
A deeper fix would be to prevent non-extension plugin components from
leaking into the global `BeanLocator` in the first place — e.g. by making
`discoverComponents` selective (only exposing Mojo-typed bindings for
non-extension plugins). That would address the latent leak that has existed
since Maven 3. However, `discoverComponents` cannot simply be skipped for
non-extension plugins because it creates the Sisu/Guice bindings required for
mojo lookup via `container.lookup()`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]