--- a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Wed Nov 23 16:16:35 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Thu Dec 01 08:57:53 2016 +0000
@@ -42,15 +42,14 @@
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Hashtable;
import java.util.Map;
+import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Set;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.Stack;
-import java.util.NoSuchElementException;
import java.util.Vector;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
@@ -59,7 +58,6 @@
import java.util.stream.StreamSupport;
import jdk.internal.perf.PerfCounter;
-import jdk.internal.module.ServicesCatalog;
import jdk.internal.loader.BootLoader;
import jdk.internal.loader.ClassLoaders;
import jdk.internal.misc.SharedSecrets;
@@ -411,7 +409,6 @@
this(checkCreateClassLoader(), null, parent);
}
-
/**
* Creates a new class loader using the <tt>ClassLoader</tt> returned by
* the method {@link #getSystemClassLoader()
@@ -431,7 +428,6 @@
this(checkCreateClassLoader(), null, getSystemClassLoader());
}
-
/**
* Returns the name of this class loader or {@code null} if
* this class loader is not named.
@@ -581,7 +577,7 @@
* @return The resulting {@code Class} object in a module defined by
* this class loader, or {@code null} if the class could not be found.
*/
- final Class<?> loadLocalClass(Module module, String name) {
+ final Class<?> loadClass(Module module, String name) {
synchronized (getClassLoadingLock(name)) {
// First, check if the class has already been loaded
Class<?> c = findLoadedClass(name);
@@ -597,34 +593,6 @@
}
/**
- * Loads the class with the specified <a href="#name">binary name</a>
- * defined by this class loader. This method returns {@code null}
- * if the class could not be found.
- *
- * @apiNote This method does not delegate to the parent class loader.
- *
- * @param name
- * The <a href="#name">binary name</a> of the class
- *
- * @return The resulting {@code Class} object in a module defined by
- * this class loader, or {@code null} if the class could not be found.
- */
- final Class<?> loadLocalClass(String name) {
- synchronized (getClassLoadingLock(name)) {
- // First, check if the class has already been loaded
- Class<?> c = findLoadedClass(name);
- if (c == null) {
- try {
- return findClass(name);
- } catch (ClassNotFoundException e) {
- // ignore
- }
- }
- return c;
- }
- }
-
- /**
* Returns the lock object for class loading operations.
* For backward compatibility, the default implementation of this method
* behaves as follows. If this ClassLoader object is registered as
@@ -724,12 +692,17 @@
* should override this method.
*
* @apiNote This method returns {@code null} rather than throwing
- * {@code ClassNotFoundException} if the class could not be found
+ * {@code ClassNotFoundException} if the class could not be found.
*
- * @implSpec The default implementation returns {@code null}.
+ * @implSpec The default implementation attempts to find the class by
+ * invoking {@link #findClass(String)} when the {@code moduleName} is
+ * {@code null}. It otherwise returns {@code null}.
*
* @param moduleName
- * The module name
+ * The module name; or {@code null} to find the class in the
+ * {@linkplain #getUnnamedModule() unnamed module} for this
+ * class loader
+
* @param name
* The <a href="#name">binary name</a> of the class
*
@@ -739,6 +712,11 @@
* @since 9
*/
protected Class<?> findClass(String moduleName, String name) {
+ if (moduleName == null) {
+ try {
+ return findClass(name);
+ } catch (ClassNotFoundException ignore) { }
+ }
return null;
}
@@ -1286,10 +1264,20 @@
* Class loader implementations that support the loading from modules
* should override this method.
*
- * @implSpec The default implementation returns {@code null}.
+ * @apiNote This method is the basis for the {@code Class} {@link
+ * Class#getResource getResource} and {@link Class#getResourceAsStream
+ * getResourceAsStream} methods. It is not subject to the rules for
+ * encapsulation specified by {@code Module} {@link
+ * Module#getResourceAsStream getResourceAsStream}.
+ *
+ * @implSpec The default implementation attempts to find the resource by
+ * invoking {@link #findResource(String)} when the {@code moduleName} is
+ * {@code null}. It otherwise returns {@code null}.
*
* @param moduleName
- * The module name
+ * The module name; or {@code null} to find a resource in the
+ * {@linkplain #getUnnamedModule() unnamed module} for this
+ * class loader
* @param name
* The resource name
*
@@ -1306,7 +1294,11 @@
* @since 9
*/
protected URL findResource(String moduleName, String name) throws IOException {
- return null;
+ if (moduleName == null) {
+ return findResource(name);
+ } else {
+ return null;
+ }
}
/**
@@ -1314,9 +1306,6 @@
* (images, audio, text, etc) that can be accessed by class code in a way
* that is independent of the location of the code.
*
- * Resources in a named module are private to that module. This method does
- * not find resource in named modules.
- *
* <p> The name of a resource is a '<tt>/</tt>'-separated path name that
* identifies the resource.
*
@@ -1325,16 +1314,30 @@
* built-in to the virtual machine is searched. That failing, this method
* will invoke {@link #findResource(String)} to find the resource. </p>
*
- * @apiNote When overriding this method it is recommended that an
- * implementation ensures that any delegation is consistent with the {@link
+ * <p> Resources in named modules are subject to the encapsulation rules
+ * specified by {@link Module#getResourceAsStream Module.getResourceAsStream}.
+ * Additionally, and except for the special case where the resource has a
+ * name ending with "{@code .class}", this method will only find resources in
+ * packages of named modules when the package is {@link Module#isOpen(String)
+ * opened} unconditionally (even if the caller of this method is in the
+ * same module as the resource). </p>
+ *
+ * @apiNote Where several modules are defined to the same class loader,
+ * and where more than one module contains a resource with the given name,
+ * then the ordering that modules are searched is not specified and may be
+ * very unpredictable.
+ * When overriding this method it is recommended that an implementation
+ * ensures that any delegation is consistent with the {@link
* #getResources(java.lang.String) getResources(String)} method.
*
* @param name
* The resource name
*
- * @return A <tt>URL</tt> object for reading the resource, or
- * <tt>null</tt> if the resource could not be found or the invoker
- * doesn't have adequate privileges to get the resource.
+ * @return {@code URL} object for reading the resource; {@code null} if
+ * the resource could not be found, a {@code URL} could not be
+ * constructed to locate the resource, the resource is in a package
+ * that is not opened unconditionally, or access to the resource is
+ * denied by the security manager.
*
* @since 1.1
*/
@@ -1356,16 +1359,24 @@
* (images, audio, text, etc) that can be accessed by class code in a way
* that is independent of the location of the code.
*
- * Resources in a named module are private to that module. This method does
- * not find resources in named modules.
- *
- * <p>The name of a resource is a <tt>/</tt>-separated path name that
+ * <p> The name of a resource is a <tt>/</tt>-separated path name that
* identifies the resource.
*
- * <p> The search order is described in the documentation for {@link
- * #getResource(String)}. </p>
+ * <p> The delegation order for searching is described in the documentation
+ * for {@link #getResource(String)}. </p>
*
- * @apiNote When overriding this method it is recommended that an
+ * <p> Resources in named modules are subject to the encapsulation rules
+ * specified by {@link Module#getResourceAsStream Module.getResourceAsStream}.
+ * Additionally, and except for the special case where the resource has a
+ * name ending with "{@code .class}", this method will only find resources in
+ * packages of named modules when the package is {@link Module#isOpen(String)
+ * opened} unconditionally (even if the caller of this method is in the
+ * same module as the resource).</p>
+ *
+ * @apiNote Where several modules are defined to the same class loader,
+ * and where more than one module contains a resource with the given name,
+ * then the ordering is not specified and may be very unpredictable.
+ * When overriding this method it is recommended that an
* implementation ensures that any delegation is consistent with the {@link
* #getResource(java.lang.String) getResource(String)} method. This should
* ensure that the first element returned by the Enumeration's
@@ -1376,9 +1387,11 @@
* The resource name
*
* @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
- * the resource. If no resources could be found, the enumeration
- * will be empty. Resources that the class loader doesn't have
- * access to will not be in the enumeration.
+ * the resource. If no resources could be found, the enumeration
+ * will be empty. Resources for which a {@code URL} cannot be
+ * constructed, are in package that is not opened unconditionally,
+ * or access to the resource is denied by the security manager,
+ * are not returned in the enumeration.
*
* @throws IOException
* If I/O errors occur
@@ -1406,9 +1419,6 @@
* can be accessed by class code in a way that is independent of the
* location of the code.
*
- * Resources in a named module are private to that module. This method does
- * not find resources in named modules.
- *
* <p> The name of a resource is a {@code /}-separated path name that
* identifies the resource.
*
@@ -1420,6 +1430,14 @@
* exception is wrapped in an {@link UncheckedIOException} that is then
* thrown.
*
+ * <p> Resources in named modules are subject to the encapsulation rules
+ * specified by {@link Module#getResourceAsStream Module.getResourceAsStream}.
+ * Additionally, and except for the special case where the resource has a
+ * name ending with "{@code .class}", this method will only find resources in
+ * packages of named modules when the package is {@link Module#isOpen(String)
+ * opened} unconditionally (even if the caller of this method is in the
+ * same module as the resource). </p>
+ *
* @apiNote When overriding this method it is recommended that an
* implementation ensures that any delegation is consistent with the {@link
* #getResource(java.lang.String) getResource(String)} method. This should
@@ -1430,9 +1448,10 @@
* The resource name
*
* @return A stream of resource {@link java.net.URL URL} objects. If no
- * resources could be found, the stream will be empty. Resources
- * that the class loader doesn't have access to will not be in the
- * stream.
+ * resources could be found, the stream will be empty. Resources
+ * for which a {@code URL} cannot be constructed, are in a package
+ * that is not opened unconditionally, or access to the resource
+ * is denied by the security manager, will not be in the stream.
*
* @see #findResources(String)
*
@@ -1455,14 +1474,21 @@
* Finds the resource with the given name. Class loader implementations
* should override this method to specify where to find resources.
*
- * Resources in a named module are private to that module. This method does
- * not find resources in named modules defined to this class loader.
+ * <p> For resources in named modules then the method must implement the
+ * rules for encapsulation specified in the {@code Module} {@link
+ * Module#getResourceAsStream getResourceAsStream} method. Additionally,
+ * it must not find non-"{@code .class}" resources in packages of named
+ * modules unless the package is {@link Module#isOpen(String) opened}
+ * unconditionally. </p>
*
* @param name
* The resource name
*
- * @return A <tt>URL</tt> object for reading the resource, or
- * <tt>null</tt> if the resource could not be found
+ * @return {@code URL} object for reading the resource; {@code null} if
+ * the resource could not be found, a {@code URL} could not be
+ * constructed to locate the resource, the resource is in a package
+ * that is not opened unconditionally, or access to the resource is
+ * denied by the security manager.
*
* @since 1.2
*/
@@ -1476,14 +1502,22 @@
* implementations should override this method to specify where to load
* resources from.
*
- * Resources in a named module are private to that module. This method does
- * not find resources in named modules defined to this class loader.
+ * <p> For resources in named modules then the method must implement the
+ * rules for encapsulation specified in the {@code Module} {@link
+ * Module#getResourceAsStream getResourceAsStream} method. Additionally,
+ * it must not find non-"{@code .class}" resources in packages of named
+ * modules unless the package is {@link Module#isOpen(String) opened}
+ * unconditionally. </p>
*
* @param name
* The resource name
*
* @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
- * the resources
+ * the resource. If no resources could be found, the enumeration
+ * will be empty. Resources for which a {@code URL} cannot be
+ * constructed, are in a package that is not opened unconditionally,
+ * or access to the resource is denied by the security manager,
+ * are not returned in the enumeration.
*
* @throws IOException
* If I/O errors occur
@@ -1491,7 +1525,7 @@
* @since 1.2
*/
protected Enumeration<URL> findResources(String name) throws IOException {
- return java.util.Collections.emptyEnumeration();
+ return Collections.emptyEnumeration();
}
/**
@@ -1541,14 +1575,21 @@
* classes. This method locates the resource through the system class
* loader (see {@link #getSystemClassLoader()}).
*
- * Resources in a named module are private to that module. This method does
- * not find resources in named modules.
+ * <p> Resources in named modules are subject to the encapsulation rules
+ * specified by {@link Module#getResourceAsStream Module.getResourceAsStream}.
+ * Additionally, and except for the special case where the resource has a
+ * name ending with "{@code .class}", this method will only find resources in
+ * packages of named modules when the package is {@link Module#isOpen(String)
+ * opened} unconditionally. </p>
*
* @param name
* The resource name
*
- * @return A {@link java.net.URL <tt>URL</tt>} object for reading the
- * resource, or <tt>null</tt> if the resource could not be found
+ * @return A {@link java.net.URL <tt>URL</tt>} to the resource; {@code
+ * null} if the resource could not be found, a URL could not be
+ * constructed to locate the resource, the resource is in a package
+ * that is not opened unconditionally or access to the resource is
+ * denied by the security manager.
*
* @since 1.1
*/
@@ -1562,17 +1603,25 @@
* {@link java.util.Enumeration <tt>Enumeration</tt>} of {@link
* java.net.URL <tt>URL</tt>} objects.
*
- * Resources in a named module are private to that module. This method does
- * not find resources in named modules.
- *
* <p> The search order is described in the documentation for {@link
* #getSystemResource(String)}. </p>
*
+ * <p> Resources in named modules are subject to the encapsulation rules
+ * specified by {@link Module#getResourceAsStream Module.getResourceAsStream}.
+ * Additionally, and except for the special case where the resource has a
+ * name ending with "{@code .class}", this method will only find resources in
+ * packages of named modules when the package is {@link Module#isOpen(String)
+ * opened} unconditionally. </p>
+ *
* @param name
* The resource name
*
- * @return An enumeration of resource {@link java.net.URL <tt>URL</tt>}
- * objects
+ * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
+ * the resource. If no resources could be found, the enumeration
+ * will be empty. Resources for which a {@code URL} cannot be
+ * constructed, are in a package that is not opened unconditionally,
+ * or access to the resource is denied by the security manager,
+ * are not returned in the enumeration.
*
* @throws IOException
* If I/O errors occur
@@ -1588,17 +1637,23 @@
/**
* Returns an input stream for reading the specified resource.
*
- * Resources in a named module are private to that module. This method does
- * not find resources in named modules.
- *
* <p> The search order is described in the documentation for {@link
* #getResource(String)}. </p>
*
+ * <p> Resources in named modules are subject to the encapsulation rules
+ * specified by {@link Module#getResourceAsStream Module.getResourceAsStream}.
+ * Additionally, and except for the special case where the resource has a
+ * name ending with "{@code .class}", this method will only find resources in
+ * packages of named modules when the package is {@link Module#isOpen(String)
+ * opened} unconditionally. </p>
+ *
* @param name
* The resource name
*
- * @return An input stream for reading the resource, or <tt>null</tt>
- * if the resource could not be found
+ * @return An input stream for reading the resource; {@code null} if the
+ * resource could not be found, the resource is in a package that
+ * is not opened unconditionally, or access to the resource is
+ * denied by the security manager.
*
* @since 1.1
*/
@@ -1616,14 +1671,20 @@
* used to load classes. This method locates the resource through the
* system class loader (see {@link #getSystemClassLoader()}).
*
- * Resources in a named module are private to that module. This method does
- * not find resources in named modules.
+ * <p> Resources in named modules are subject to the encapsulation rules
+ * specified by {@link Module#getResourceAsStream Module.getResourceAsStream}.
+ * Additionally, and except for the special case where the resource has a
+ * name ending with "{@code .class}", this method will only find resources in
+ * packages of named modules when the package is {@link Module#isOpen(String)
+ * opened} unconditionally. </p>
*
* @param name
* The resource name
*
- * @return An input stream for reading the resource, or <tt>null</tt>
- * if the resource could not be found
+ * @return An input stream for reading the resource; {@code null} if the
+ * resource could not be found, the resource is in a package that
+ * is not opened unconditionally, or access to the resource is
+ * denied by the security manager.
*
* @since 1.1
*/
@@ -2709,33 +2770,7 @@
private static native AssertionStatusDirectives retrieveDirectives();
- /**
- * Returns the ServiceCatalog for modules defined to this class loader
- * or {@code null} if this class loader does not have a services catalog.
- */
- ServicesCatalog getServicesCatalog() {
- return servicesCatalog;
- }
-
- /**
- * Returns the ServiceCatalog for modules defined to this class loader,
- * creating it if it doesn't already exist.
- */
- ServicesCatalog createOrGetServicesCatalog() {
- ServicesCatalog catalog = servicesCatalog;
- if (catalog == null) {
- catalog = ServicesCatalog.create();
- boolean set = trySetObjectField("servicesCatalog", catalog);
- if (!set) {
- // beaten by someone else
- catalog = servicesCatalog;
- }
- }
- return catalog;
- }
-
- // the ServiceCatalog for modules associated with this class loader.
- private volatile ServicesCatalog servicesCatalog;
+ // -- Misc --
/**
* Returns the ConcurrentHashMap used as a storage for ClassLoaderValue(s)