Using non-parallel custom class loaders for Layer configurations

David M. Lloyd david.lloyd at redhat.com
Thu Sep 8 22:29:36 UTC 2016


Is it not necessary that any class loader in use by a Layer must be 
parallel-capable?  Otherwise it seems like deadlocks could occur in 
certain situations when there are references that are cyclic with 
respect to class loaders mapped by the mapping function.

On that note, there is in fact no good way for user code to determine 
whether or not a class loader is indeed parallel-capable, which is often 
a critical question in module systems, especially when users can provide 
specialized class loader implementations.  Right now you can only do 
something (awful) like this (e.g. in your base ClassLoader constructor):

         if (getClassLoadingLock("$TEST$") == this) {
             throw new Error("Cannot instantiate non-parallel subclass");
         }

Would it be possible to include a method like this (pretty old patch I 
had laying around):

diff --git a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java 
b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java
index 1bb1580..3def10e 100644
--- a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java
+++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java
@@ -469,6 +477,15 @@ public abstract class ClassLoader {
          return lock;
      }

+    /**
+     * Determine whether this class loader is parallel-capable.
+     *
+     * @return {@code true} if the class loader is parallel-capable, 
{@code false} otherwise
+     */
+    protected final boolean isParallelCapable() {
+        return ParallelLoaders.isRegistered(getClass());
+    }
+
      // This method is invoked by the virtual machine to load a class.
      private Class<?> loadClassInternal(String name)
          throws ClassNotFoundException

Alternatively, the method could be made static and protected, only 
returning true if the calling class is a class loader that is parallel 
capable, something like this (against a newer branch):

diff --git a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java 
b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java
index 0139123..06a5909 100644
--- a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java
+++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java
@@ -1421,6 +1421,19 @@ public abstract class ClassLoader {
      }

      /**
+     * Determine whether the calling class is a parallel-capable class 
loader.
+     *
+     * @return true if the caller is a parallel-capable class loader 
and false otherwise
+     *
+     * @since  9
+     */
+    @CallerSensitive
+    protected static boolean isParallelCapable() {
+        final Class<?> callerClass = Reflection.getCallerClass();
+        return ClassLoader.class.isAssignableFrom(callerClass) && 
ParallelLoaders.isRegistered(callerClass.asSubclass(ClassLoader.class));
+    }
+
+    /**
       * Find a resource of the specified name from the search path used 
to load
       * classes.  This method locates the resource through the system class
       * loader (see {@link #getSystemClassLoader()}).

WDYT?

-- 
- DML


More information about the jigsaw-dev mailing list