Summary
Change the specification of java.nio.file.FileSystems.getDefault()
to specify that it locates a custom default file system provider using the "default system class loader" instead of the "system class loader".
Problem
If an application is deployed to use a custom default file system provider (-Djava.nio.file.DefaultFileSystemProvider=$CLASS
), and a custom system class loader (-Djava.system.class.loader=$CLASS
), and the initialisation of the custom system class loader uses the file system APIs, then it leads to circular initialization of the system class loader and IllegalStateException
. The detection of this circular initialization is specified by ClassLoader.getSystemClassLoader()
.
Solution
Change the specification of java.nio.file.FileSystems.getDefault()
to locate the custom default file system provider using the "default system class loader" instead of the "system class loader". The default system class loader is the application class loader when running with a custom system class loader.
Additionally, expand the specification to specify that the custom default file system provider must be public, in a package that is exported to at least java.base, and that its constructor is public.
Specification
* <p> If the system property {@code java.nio.file.spi.DefaultFileSystemProvider}
- * is defined then it is taken to be a list of one or more fully-qualified
- * names of concrete provider classes identified by the URI scheme
- * {@code "file"}. Where the property is a list of more than one name then
- * the names are separated by a comma. Each class is loaded, using the system
- * class loader, and instantiated by invoking a one argument constructor
- * whose formal parameter type is {@code FileSystemProvider}. The providers
- * are loaded and instantiated in the order they are listed in the property.
+ * is defined then it is taken to be a list of one or more fully-qualified names
+ * of concrete provider classes identified by the URI scheme {@code "file"}.
+ * If the property is a list of more than one name then the names are separated
+ * by a comma character. Each provider class is a {@code public} class with a
+ * {@code public} constructor that has one formal parameter of type {@code
+ * FileSystemProvider}. If the provider class is in a named module then the module
+ * exports the package containing the provider class to at least {@code java.base}.
+ * Each provider class is loaded, using the
+ * {@linkplain ClassLoader#getSystemClassLoader() default system class loader},
+ * and instantiated by invoking the constructor. The providers are loaded and
+ * instantiated in the order they are listed in the property.
- csr of
-
JDK-8346573 Can't use custom default file system provider with custom system class loader
-
- Resolved
-