--- old/jdk/src/java.base/share/classes/java/lang/ClassLoader.java 2016-11-02 10:10:05.000000000 -0700 +++ new/jdk/src/java.base/share/classes/java/lang/ClassLoader.java 2016-11-02 10:10:04.000000000 -0700 @@ -222,6 +222,9 @@ // must be added *after* it. private final ClassLoader parent; + // class loader name + private final String name; + // the unnamed module for this ClassLoader private final Module unnamedModule; @@ -331,6 +334,14 @@ } private static Void checkCreateClassLoader() { + return checkCreateClassLoader(null); + } + + private static Void checkCreateClassLoader(String name) { + if (name != null && name.isEmpty()) { + throw new IllegalArgumentException("name must be non-empty or null"); + } + SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkCreateClassLoader(); @@ -338,7 +349,8 @@ return null; } - private ClassLoader(Void unused, ClassLoader parent) { + private ClassLoader(Void unused, String name, ClassLoader parent) { + this.name = name; this.parent = parent; this.unnamedModule = SharedSecrets.getJavaLangReflectModuleAccess() @@ -356,6 +368,27 @@ } /** + * Creates a new class loader of the specified name and using the + * specified parent class loader for delegation. + * + * @param name class loader name; or {@code null} if not named + * @param parent the parent class loader + * + * @throws IllegalArgumentException if the given name is empty. + * + * @throws SecurityException + * If a security manager exists and its + * {@link SecurityManager#checkCreateClassLoader()} + * method doesn't allow creation of a new class loader. + * + * @since 9 + */ + protected ClassLoader(String name, ClassLoader parent) { + this(checkCreateClassLoader(name), name, parent); + } + + + /** * Creates a new class loader using the specified parent class loader for * delegation. * @@ -375,9 +408,10 @@ * @since 1.2 */ protected ClassLoader(ClassLoader parent) { - this(checkCreateClassLoader(), parent); + this(checkCreateClassLoader(), null, parent); } + /** * Creates a new class loader using the ClassLoader returned by * the method {@link #getSystemClassLoader() @@ -394,7 +428,31 @@ * of a new class loader. */ protected ClassLoader() { - this(checkCreateClassLoader(), getSystemClassLoader()); + this(checkCreateClassLoader(), null, getSystemClassLoader()); + } + + + /** + * Returns the name of this class loader or {@code null} if + * this class loader is not named. + * + * @apiNote This method is non-final for compatibility. If this + * method is overridden, this method must return the same name + * as specified when this class loader was instantiated. + * + * @return name of this class loader; or {@code null} if + * this class loader is not named. + * + * @since 9 + */ + public String getName() { + return name; + } + + // package-private used by StackTraceElement to avoid + // calling the overrideable getName method + final String name() { + return name; } // -- Class -- @@ -1628,6 +1686,9 @@ * platform classes are visible to * the platform class loader. * + * @implNote The name of the builtin platform class loader is + * {@code "platform"}. + * * @return The platform {@code ClassLoader}. * * @throws SecurityException @@ -1681,7 +1742,8 @@ * this method during startup should take care not to cache the return * value until the system is fully initialized. * - *

The class path used by the built-in system class loader is determined + *

The name of the built-in system class loader is {@code "app"}. + * The class path used by the built-in system class loader is determined * by the system property "{@code java.class.path}" during early * initialization of the VM. If the system property is not defined, * or its value is an empty string, then there is no class path