Compatibility with Gradle's classloader cleanup (closes #427)

Gradle has a cleanup mechanism in place that reflectively accesses
the ClassInfo.klazz field.  This change prevents an exception being
thrown by the cleanup method.  This workaround also means that the
cleanup strategy will no longer work, but the fix to replace klazz with a
WeakReference should eliminate the need for the explicit cleanup.

For more details, see dev mailing list thread:
https://mail-archives.apache.org/mod_mbox/incubator-groovy-dev/201609.mbox/%3CCAHPL-JkQ%2BU8PfaxyVhtE%3DvGV%2BsXXmCzxOsCR8UbBww6P2vskPg%40mail.gmail.com%3E


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/82c9d20a
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/82c9d20a
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/82c9d20a

Branch: refs/heads/GROOVY_2_4_X
Commit: 82c9d20a160c7e4f59630f163a68df82f5e0eba4
Parents: ed85b20
Author: John Wagenleitner <jwagenleit...@apache.org>
Authored: Wed Sep 21 22:20:08 2016 -0700
Committer: John Wagenleitner <jwagenleit...@apache.org>
Committed: Wed Sep 21 22:24:28 2016 -0700

----------------------------------------------------------------------
 .../codehaus/groovy/reflection/ClassInfo.java   | 24 +++++++++++++++-----
 1 file changed, 18 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/82c9d20a/src/main/org/codehaus/groovy/reflection/ClassInfo.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/reflection/ClassInfo.java 
b/src/main/org/codehaus/groovy/reflection/ClassInfo.java
index 221b905..542c8e4 100644
--- a/src/main/org/codehaus/groovy/reflection/ClassInfo.java
+++ b/src/main/org/codehaus/groovy/reflection/ClassInfo.java
@@ -49,7 +49,19 @@ public class ClassInfo implements Finalizable {
     private final LazyClassLoaderRef artifactClassLoader;
     private final LockableObject lock = new LockableObject();
     public final int hash = -1;
-    private final WeakReference<Class<?>> klazz;
+    private final WeakReference<Class<?>> classRef;
+
+    // TODO: should be able to remove the klazz field once 2.5 becomes the 
mainline release
+    // Gradle has a cleanup mechanism in place to reflectively access this 
klazz field.
+    // The klazz field is being kept for compatibility so as to not break 
builds that depend
+    // on versions of Groovy after the field was changed to a WeakReference 
(classRef).  It
+    // appears that Gradle only performs the cleanup when it detects a groovy 
version of 2.4.x,
+    // so the klazz field and placeholder Sentinel class can likely be safely 
removed once
+    // the release version bumps to 2.5 (or beyond).
+    // See:
+    // 
https://github.com/gradle/gradle/blob/711f64/subprojects/core/src/main/java/org/gradle/api/internal/classloading/LeakyOnJava7GroovySystemLoader.java#L74
+    private static final class Sentinel {}
+    private static final Class<?> klazz = Sentinel.class;
 
     private final AtomicInteger version = new AtomicInteger();
 
@@ -76,7 +88,7 @@ public class ClassInfo implements Finalizable {
     private static final GlobalClassSet globalClassSet = new GlobalClassSet();
 
     ClassInfo(Class klazz) {
-       this.klazz = new WeakReference<Class<?>>(klazz);
+        this.classRef = new WeakReference<Class<?>>(klazz);
         cachedClassRef = new LazyCachedClassRef(softBundle, this);
         artifactClassLoader = new LazyClassLoaderRef(softBundle, this);
     }
@@ -117,7 +129,7 @@ public class ClassInfo implements Finalizable {
      * @return the {@code Class} associated with this {@code ClassInfo}, else 
{@code null}
      */
     public final Class<?> getTheClass() {
-        return klazz.get();
+        return classRef.get();
     }
 
     public CachedClass getCachedClass() {
@@ -239,7 +251,7 @@ public class ClassInfo implements Finalizable {
             return answer;
         }
 
-        answer = mccHandle.create(klazz.get(), metaClassRegistry);
+        answer = mccHandle.create(classRef.get(), metaClassRegistry);
         answer.initialize();
 
         if (GroovySystem.isKeepJavaMetaClasses()) {
@@ -403,7 +415,7 @@ public class ClassInfo implements Finalizable {
         }
 
         public CachedClass initValue() {
-            return createCachedClass(info.klazz.get(), info);
+            return createCachedClass(info.classRef.get(), info);
         }
     }
 
@@ -416,7 +428,7 @@ public class ClassInfo implements Finalizable {
         }
 
         public ClassLoaderForClassArtifacts initValue() {
-            return new ClassLoaderForClassArtifacts(info.klazz.get());
+            return new ClassLoaderForClassArtifacts(info.classRef.get());
         }
     }
 

Reply via email to