You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Paul King (Jira)" <ji...@apache.org> on 2026/08/19 09:04:00 UTC

[jira] [Resolved] (GROOVY-12280) AwaitableAdapterRegistry.awaitableCache pins the Groovy class loader via ClassValue associations on platform-class keys

     [ https://issues.apache.org/jira/browse/GROOVY-12280?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Paul King resolved GROOVY-12280.
--------------------------------
    Fix Version/s: 6.0.0-beta-3
         Assignee: Paul King
       Resolution: Fixed

> AwaitableAdapterRegistry.awaitableCache pins the Groovy class loader via ClassValue associations on platform-class keys
> -----------------------------------------------------------------------------------------------------------------------
>
>                 Key: GROOVY-12280
>                 URL: https://issues.apache.org/jira/browse/GROOVY-12280
>             Project: Groovy
>          Issue Type: Bug
>            Reporter: Paul King
>            Assignee: Paul King
>            Priority: Major
>             Fix For: 6.0.0-beta-3
>
>
> {{AwaitableAdapterRegistry}} caches adapter lookups in a raw {{java.lang.ClassValue}} keyed by the awaited object's class. The common keys are platform classes — {{CompletableFuture}}, {{CompletionStage}}, {{Flow.Publisher}} implementations — while the cached value (the adapter instance) is loaded by Groovy's class loader. A {{ClassValue}} association lives as long as its key class ([JDK-8136353|https://bugs.openjdk.org/browse/JDK-8136353], working as intended), so an association on an effectively immortal platform class holds the adapter, and through it the entire Groovy class loader, for the lifetime of the JVM. In the per-webapp deployment topology this re-creates exactly the pinning GROOVY-12142 removed elsewhere: metaspace growth on every redeployment once any {{await}} has executed.
> Note this site is not covered by the {{groovy.use.classvalue=false}} escape hatch restored in GROOVY-12142 — it does not go through {{GroovyClassValueFactory}} (which is package-private in {{org.codehaus.groovy.reflection}} and not reachable from {{groovy.concurrent}}).
> Unlike the general {{ClassInfo}} problem (see the companion investigation ticket), the preconditions for the {{SoftReference}} strategy are already satisfied here by construction: recomputation is a cheap, pure scan over the adapter list, and the registry already rebuilds the cache on mutation. Proposed fix: wrap values in {{SoftReference}} with the check-remove-recompute discipline (on a cleared reference, {{remove(...)}} the association and recompute), optionally also widening {{GroovyClassValueFactory}} so this site honors the escape hatch for consistency.
> Follow-up from review discussion on [PR #2798|https://github.com/apache/groovy/pull/2798] (GROOVY-12142).



--
This message was sent by Atlassian Jira
(v8.20.10#820010)