cmunier opened a new pull request, #1918: URL: https://github.com/apache/maven-mvnd/pull/1918
After each build, mvnd evicts the cached realms that refer to artifacts in the build tree, e.g. the realm of a Maven plugin built in the same reactor, and disposes them. These realms were never garbage collected: Sisu's JSR250 `LifecycleManager` caches the lifecycle of every component class with strong `Class` keys and does not flush it when a realm is disposed (eclipse-sisu/sisu-project#281). So the daemon kept one more copy of such a plugin with every build, and metaspace grew until `mvnd --stop`. The new component `RealmDisposer` disposes the realm like before and then calls `LifecycleManager.flushCacheFor(clazz -> clazz.getClassLoader() == realm)`. Sisu added this method in 0.9.0.M3 for this purpose. `InvalidatingPluginRealmCache`, `InvalidatingExtensionRealmCache` and `InvalidatingPluginDescriptorCache` use it instead of calling `disposeRealm` themselves. The `LifecycleManager` is the private `delegate` of the injected `BeanManager` (`PlexusLifecycleManager`), so it is read via reflection. If that fails, only the flush is skipped. This is a workaround for the Sisu bug. With eclipse-sisu/sisu-project#282, Sisu flushes the cache itself when a realm is disposed, the flush here finds nothing, and `RealmDisposer` can be removed again. Sisu comes with the embedded Maven distribution (Sisu 1.1.0 on `master` with Maven 4.0.0-rc-7, 1.0.0 on `mvnd-1.x` with Maven 3.9.16), so the Sisu fix only reaches mvnd after a Sisu release, a Maven release that includes it, and a Maven update i n mvnd. For `mvnd-1.x` (Maven 3.9.x) that may not happen at all. If you prefer to wait for Sisu instead, the issue can stay open until then. Note: if a component with `@PreDestroy` from an evicted realm was never released, `dispose()` of the container no longer calls its `@PreDestroy` after the flush. Such a component keeps the realm reachable anyway, and the realm is no longer used once it is evicted. Verified: - New `RealmDisposerTest`: creates a child realm in a container with JSR250 lifecycle, lets the `BeanManager` manage a class of that realm (as Sisu does for every bound component class), disposes the realm and checks that it is garbage collected. Fails without the flush. - `./mvnw verify -pl '!integration-tests,!dist'`, and `ModuleAndPluginTest`, `ExtensionsTest`, `ResidentExtensionsTest`, `SingleModuleTest`, `MultiModuleTest`, `StopStatusTest`. - Manually with the `module-and-plugin` test project: `mvnd clean install` four times in a fresh daemon, then `jcmd <pid> GC.run` and counting the loaded `HelloMojo` classes with `jcmd <pid> VM.class_hierarchy`: 1, 2, 3, 4 without this change; 0 after every build with it. If this is fine for you, I'll open the same change for `mvnd-1.x` (cherry-pick with one small conflict). It matters most there: `mvnd-1.x` embeds Maven 3.9.x, which may never get a Sisu version with the fix. Fixes #1917 AI disclosure: drafted with Claude Code (Anthropic Claude Opus 5.5, interactive mode). I have reviewed and tested the change myself. --- - [x] I hereby declare this contribution to be licensed under the [Apache License Version 2.0, January 2004](https://www.apache.org/licenses/LICENSE-2.0) - [ ] I hereby declare that I have filed an [Apache Individual Contributor License Agreement](https://www.apache.org/licenses/icla.pdf). -- 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]
