Summary
The API doc of java.net.URLClassLoader
and java.security.SecureClassLoader
constructors is updated to specify their behaviour when null
is passed for the parent
ClassLoader
.
Problem
The constructors in URLClassLoader
and SecureClassLoader
allow for a parent ClassLoader
to be passed. These constructors allow null
for parent
, to represent the bootstrap class loader. In Java versions 9 and above, only a specific set of modules are mapped (at JDK build time) to the bootstrap class loader. Some modules like java.sql
are visible to the platform class loader but not to the bootstrap class loader. Passing null
for parent
to the URLClassLoader
or the SecureClassLoader
constructors means that some platform classes will not be visible to these class loaders. Applications trying to load platform classes through such class loaders may encounter java.lang.ClassNotFoundException
. This behaviour is currently not noted in the documentation of these constructors. Adding a note about this will help applications be aware of this detail and choose a different and more appropriate parent class loader.
Solution
A @apiNote
will be added to the constructors of URLClassLoader
and SecureClassLoader
.
Specification
diff --git a/src/java.base/share/classes/java/net/URLClassLoader.java b/src/java.base/share/classes/java/net/URLClassLoader.java
index 90bb1c56f114e..4b579554e0adc 100644
--- a/src/java.base/share/classes/java/net/URLClassLoader.java
+++ b/src/java.base/share/classes/java/net/URLClassLoader.java
+ * @apiNote If {@code parent} is specified as {@code null} (for the
+ * bootstrap class loader) then there is no guarantee that all platform
+ * classes are visible.
+ * See {@linkplain ClassLoader##builtinLoaders Run-time Built-in Class Loaders}
+ * for information on the bootstrap class loader and other built-in class loaders.
+ *
* @param urls the URLs from which to load classes and resources
- * @param parent the parent class loader for delegation
+ * @param parent the parent class loader for delegation, can be {@code null}
+ * for the bootstrap class loader
* @throws NullPointerException if {@code urls} or any of its
* elements is {@code null}.
*/
public URLClassLoader(URL[] urls, ClassLoader parent) {
/**
* Constructs a new URLClassLoader for the specified URLs using the
- * default delegation parent {@code ClassLoader}. The URLs will
- * be searched in the order specified for classes and resources after
- * first searching in the parent class loader. Any URL that ends with
- * a '/' is assumed to refer to a directory. Otherwise, the URL is
- * assumed to refer to a JAR file which will be downloaded and opened
- * as needed.
+ * {@linkplain ClassLoader#getSystemClassLoader() system class loader
+ * as the parent}. The URLs will be searched in the order
+ * specified for classes and resources after first searching in the
+ * parent class loader. Any URL that ends with a '/' is assumed to
+ * refer to a directory. Otherwise, the URL is assumed to refer to
+ * a JAR file which will be downloaded and opened as needed.
*
* @param urls the URLs from which to load classes and resources
*
public URLClassLoader(URL[] urls) {
+ * @apiNote If {@code parent} is specified as {@code null} (for the
+ * bootstrap class loader) then there is no guarantee that all platform
+ * classes are visible.
+ * See {@linkplain ClassLoader##builtinLoaders Run-time Built-in Class Loaders}
+ * for information on the bootstrap class loader and other built-in class loaders.
+ *
* @param urls the URLs from which to load classes and resources
- * @param parent the parent class loader for delegation
+ * @param parent the parent class loader for delegation, can be {@code null}
+ * for the bootstrap class loader
* @param factory the URLStreamHandlerFactory to use when creating URLs
*
* @throws NullPointerException if {@code urls} or any of its
public URLClassLoader(URL[] urls, ClassLoader parent,
URLStreamHandlerFactory factory) {
+ * @apiNote If {@code parent} is specified as {@code null} (for the
+ * bootstrap class loader) then there is no guarantee that all platform
+ * classes are visible.
+ * See {@linkplain ClassLoader##builtinLoaders Run-time Built-in Class Loaders}
+ * for information on the bootstrap class loader and other built-in class loaders.
+ *
* @param name class loader name; or {@code null} if not named
* @param urls the URLs from which to load classes and resources
- * @param parent the parent class loader for delegation
+ * @param parent the parent class loader for delegation, can be {@code null}
+ * for the bootstrap class loader
*
* @throws IllegalArgumentException if the given name is empty.
* @throws NullPointerException if {@code urls} or any of its
public URLClassLoader(String name,
URL[] urls,
ClassLoader parent) {
+ * @apiNote If {@code parent} is specified as {@code null} (for the
+ * bootstrap class loader) then there is no guarantee that all platform
+ * classes are visible.
+ * See {@linkplain ClassLoader##builtinLoaders Run-time Built-in Class Loaders}
+ * for information on the bootstrap class loader and other built-in class loaders.
+ *
* @param name class loader name; or {@code null} if not named
* @param urls the URLs from which to load classes and resources
- * @param parent the parent class loader for delegation
+ * @param parent the parent class loader for delegation, can be {@code null}
+ * for the bootstrap class loader
* @param factory the URLStreamHandlerFactory to use when creating URLs
*
* @throws IllegalArgumentException if the given name is empty.
public URLClassLoader(String name, URL[] urls, ClassLoader parent,
URLStreamHandlerFactory factory) {
diff --git a/src/java.base/share/classes/java/security/SecureClassLoader.java b/src/java.base/share/classes/java/security/SecureClassLoader.java
index 8a6ba76e211ac..b398d7332d717 100644
--- a/src/java.base/share/classes/java/security/SecureClassLoader.java
+++ b/src/java.base/share/classes/java/security/SecureClassLoader.java
*
- * @param parent the parent ClassLoader
+ * @apiNote If {@code parent} is specified as {@code null} (for the
+ * bootstrap class loader) then there is no guarantee that all platform
+ * classes are visible.
+ * See {@linkplain ClassLoader##builtinLoaders Run-time Built-in Class Loaders}
+ * for information on the bootstrap class loader and other built-in class loaders.
+ *
+ * @param parent the parent ClassLoader, can be {@code null} for the bootstrap
+ * class loader
*/
protected SecureClassLoader(ClassLoader parent) {
/**
- * Creates a new {@code SecureClassLoader} using the default parent class
- * loader for delegation.
+ * Creates a new {@code SecureClassLoader} using the
+ * {@linkplain ClassLoader#getSystemClassLoader() system class loader as the parent}.
*/
protected SecureClassLoader() {
+ * @apiNote If {@code parent} is specified as {@code null} (for the
+ * bootstrap class loader) then there is no guarantee that all platform
+ * classes are visible.
+ * See {@linkplain ClassLoader##builtinLoaders Run-time Built-in Class Loaders}
+ * for information on the bootstrap class loader and other built-in class loaders.
+ *
* @param name class loader name; or {@code null} if not named
- * @param parent the parent class loader
+ * @param parent the parent class loader, can be {@code null} for the bootstrap
+ * class loader
*
* @throws IllegalArgumentException if the given name is empty.
*
protected SecureClassLoader(String name, ClassLoader parent) {
- csr of
-
JDK-8228773 URLClassLoader constructors should include API note warning that the parent should not be null
-
- Resolved
-