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

Reply via email to