You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by jw...@apache.org on 2017/06/24 18:47:17 UTC

groovy git commit: GROOVY-8230: Deadlock in GroovyClassLoader (closes #561)

Repository: groovy
Updated Branches:
  refs/heads/master fa3c2719c -> cf8107d5f


GROOVY-8230: Deadlock in GroovyClassLoader (closes #561)


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

Branch: refs/heads/master
Commit: cf8107d5f3d065b74b48e992d803f02f156680b5
Parents: fa3c271
Author: John Wagenleitner <jw...@apache.org>
Authored: Sun Jun 18 17:16:07 2017 -0700
Committer: John Wagenleitner <jw...@apache.org>
Committed: Sat Jun 24 11:43:50 2017 -0700

----------------------------------------------------------------------
 src/main/groovy/lang/GroovyClassLoader.java | 28 +++++++++++++++++++++---
 1 file changed, 25 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/cf8107d5/src/main/groovy/lang/GroovyClassLoader.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/lang/GroovyClassLoader.java b/src/main/groovy/lang/GroovyClassLoader.java
index 11dedfd..394627b 100644
--- a/src/main/groovy/lang/GroovyClassLoader.java
+++ b/src/main/groovy/lang/GroovyClassLoader.java
@@ -963,23 +963,45 @@ public class GroovyClassLoader extends URLClassLoader {
 
     /**
      * Removes all classes from the class cache.
+     * <p>
+     * In addition to internal caches this method also clears any
+     * previously set MetaClass information for the given set of
+     * classes being removed.
      *
      * @see #getClassCacheEntry(String)
      * @see #setClassCacheEntry(Class)
      * @see #removeClassCacheEntry(String)
      */
     public void clearCache() {
+        Class<?>[] clearedClasses;
         synchronized (classCache) {
-            for (Class cl : classCache.values()) {
-                InvokerHelper.removeClass(cl);
-            }
+            clearedClasses = getLoadedClasses();
             classCache.clear();
         }
         synchronized (sourceCache) {
             sourceCache.clear();
         }
+        for (Class<?> c : clearedClasses) {
+            // Another Thread may be using an instance of this class
+            // (for the first time) requiring a ClassInfo lock and
+            // classloading which would require a lock on classCache.
+            // The following locks on ClassInfo and to avoid deadlock
+            // should not be done with a classCache lock.
+            InvokerHelper.removeClass(c);
+        }
     }
 
+    /**
+     * Closes this GroovyClassLoader and clears any caches it maintains.
+     * <p>
+     * No use should be made of this instance after this method is
+     * invoked. Any classes that are already loaded are still accessible.
+     *
+     * @throws IOException
+     * @see URLClassLoader#close()
+     * @see #clearCache()
+     * @since 2.5.0
+     */
     @Override
     public void close() throws IOException {
         super.close();