[ 
https://issues.apache.org/jira/browse/GROOVY-8092?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15886539#comment-15886539
 ] 

Jesse Glick commented on GROOVY-8092:
-------------------------------------

bq. we have to go back a step, and then we are at the meta class not holding a 
non-weak reference at an arbitrary class. The same for MetaMethod and 
MetaProperty and in the end also for MetaMethodIndex

Exactly—no cached metadata may directly or indirectly hold a non-weak reference 
to a {{Class}} defined in an application-created {{ClassLoader}}.

bq. Basically you tell me to put the meta classes into the GroovyClassLoader 
and make ClassInfos weak references in those cases.

No my point was that if the root cache is being held as an instance field of 
the affected {{GroovyClassLoader}}, rather than a {{static}} field somewhere, 
then you can use _strong_ references and fear neither memory leaks nor 
gratuitous metadata recalculation, since a {{ClassLoader}} and every {{Class}} 
it defines are mutually strongly held anyway. It just means that the cache 
access code needs to have a switch statement: one case to handle Groovy-defined 
classes, one to handle others.

This solution applies to any case where the metadata refers to exactly one 
{{Class}}: class metadata à la {{BeanInfo}}, etc. Whether it can be adapted 
also to method metadata is more subtle, since the defining class and each 
parameter type could be considered part of the metadata, and these types could 
have been defined in different loaders. In principle you should be safe holding 
a strong reference to the defining class, since a method could not possibly 
have declared arguments of types defined in a loader which the defining class’ 
loader does not already hold a strong reference to (via {{ClassLoader.parent}} 
or some OSGi-like multiparent analogue). Unfortunately from my tests it seems 
that Groovy caches more than this: if a {{URLClassLoader}} (say) defines some 
method

{code}
package p;
public class C {
    public static void whatever(Object o) {}
}
{code}

and it is called from a script

{code}
p.C.whatever(this)
{code}

Groovy seems to cache the fact that {{p.C.whatever}} called on {{Script123}} 
indeed resolves to {{whatever(Object)}}, and this _statically held_ 
{{MetaMethodIndex}} holds a reference to {{Script123}}. If such a cache is 
truly needed, it would need to be reworked to be held from the 
{{GroovyClassLoader}}.

bq. what scenarios are left in which Groovy has to handle classes coming from a 
loader child to the class loader, that loaded Groovy

Happens in Jenkins from time to time. You have a {{GroovyClassLoader}} (per 
build) → some miscellaneous {{URLClassLoader}} (in a plugin) → 
{{AppClassLoader}} with {{groovy.jar}} (in Jenkins core), and some classes 
defined in the intermediate plugin loader are used from the script. Groovy has 
no way of knowing what the lifecycle of that intermediate loader is supposed to 
be, so it must keep only weak references to those classes.

bq. Another such environment is of course anything with OSGI

Jenkins does not use OSGi but has a very similar {{ClassLoader}} DAG, as do 
other applications.

For the “unknown loader” case, an alternative to {{ReferenceType.WEAK}} would 
be a timed reference: hold a strong reference to its referent for, say, a few 
minutes since last access, then discard it. Would behave tolerably for most 
applications. You would need an easy way to override the timeout for use from 
tests.

> Compatibility issues between groovy 2.4.8 and jenkins workflow-cps-plugin  
> 2.23
> -------------------------------------------------------------------------------
>
>                 Key: GROOVY-8092
>                 URL: https://issues.apache.org/jira/browse/GROOVY-8092
>             Project: Groovy
>          Issue Type: Bug
>          Components: groovy-runtime
>    Affects Versions: 2.4.8
>         Environment: Jenkins 2.19-stable with a single commit that bumps 
> groovy 2.4.8
> workflow-cps-plugin 2.23
>            Reporter: Ion Alberdi
>
> Created the issue on jenkins first
> https://issues.jenkins-ci.org/browse/JENKINS-42189
> Creating it here, in case the fix may be developed in groovy itself.



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)

Reply via email to