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