gnodet commented on issue #12522: URL: https://github.com/apache/maven/issues/12522#issuecomment-5068726217
## Follow-up: Investigation into preventing the leak at source Following up on the root cause analysis above — I investigated whether we can prevent non-extension plugin components from leaking into the global `BeanLocator` in the first place, rather than defensively handling provisioning failures. ### What `discoverComponents` does internally When `DefaultMavenPluginManager.discoverPluginComponents()` calls `container.discoverComponents(pluginRealm, ...)`, the `DefaultPlexusContainer` creates three module types: 1. **`ComponentDescriptorBeanModule`** — mojos from `plugin.xml` component descriptors 2. **`PlexusXmlBeanModule`** — components from `plexus.xml` (if present in the JAR) 3. **`PlexusAnnotatedBeanModule`** — `@Named` JSR 330 components discovered via `META-INF/sisu/javax.inject.Named` index files All three are passed to `addPlexusInjector()`, which calls `Guice.createInjector()` and automatically registers everything with the global `MutableBeanLocator`. Module 3 (`PlexusAnnotatedBeanModule`) is the source of the leak — it scans dependency JARs and discovers components like Tycho's `BndProjectExecutionListener`. ### Why we can't just skip `PlexusAnnotatedBeanModule` for non-extension plugins I prototyped an approach that only built `ComponentDescriptorBeanModule` (mojos) for non-extension plugins, skipping the annotation scanning. This broke plugin dependency wiring: ``` [ERROR] No implementation for org.apache.maven.shared.filtering.MavenResourcesFiltering was bound. ``` `maven-resources-plugin:3.3.1` depends on `maven-filtering-3.4.0.jar`, which ships `DefaultMavenResourcesFiltering` as a `@Named` component listed in `META-INF/sisu/javax.inject.Named`. Without `PlexusAnnotatedBeanModule` scanning that index, the mojo's `@Inject MavenResourcesFiltering` dependency has no binding and the plugin fails. ### The dual-purpose problem `PlexusAnnotatedBeanModule` serves two inseparable purposes: 1. **Plugin-internal wiring** — discovers components the plugin depends on (e.g. `DefaultMavenResourcesFiltering`). Without this, `@Inject`-ed mojo dependencies fail. 2. **Global registration** — every discovered component goes into `BeanLocator` via `Guice.createInjector()` and becomes visible in all Sisu-injected `List<T>`. This is the leak. These are coupled inside Sisu's `addPlexusInjector` → `Guice.createInjector()` → auto-registered with `MutableBeanLocator`. There is no public Sisu API to create a "private" injector whose bindings are available for local `container.lookup()` but not visible in `BeanLocator.locate()` live lists. ### Conclusion A proper fix at the source (preventing the leak) would require Sisu-level changes — for example, realm-scoped visibility for `BeanLocator.locate()`, or a "private injector" mode where bindings are available for direct lookup but excluded from live list iteration. Without such Sisu changes, the defensive iteration in PR #12528 is the right level of fix at the Maven layer. It handles the symptom correctly: catching `ProvisionException` during lazy provisioning and skipping unprovisionable listeners. Note: @cstamas is correct that the Sisu-backed Plexus shim also injects live lists (the comment by Igor Fedorenko at `CompoundProjectExecutionListener` line 31 confirms this was a known concern). The reason Maven 3 didn't hit this in practice likely comes down to timing and which specific plugins happened to register `ProjectExecutionListener` implementations — the latent bug was always there. -- 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]
