Changing the default file system provider is broken :(

forax at univ-mlv.fr forax at univ-mlv.fr
Sat Apr 22 18:10:48 UTC 2017


Hi Peter 

> Hi Remi,

> On 04/22/2017 01:20 PM, Remi Forax wrote:

>> Ooops !
>> if you use the module path, you can not change the default system provider
>> mechanism anymore,
>> mostly because the module implementation internally uses java.nio.file.Path at
>> different places.

>> First, trying to initialize the default system provider in Java code do not work
>> at all,
>> calling
>>   System.setProperty("java.nio.file.spi.DefaultFileSystemProvider", "...");
>> in a main does nothing because the jigsaw implementation has already loaded the
>> default implementation to be able to inspect the modules.

>> Then, if you try to use the command line
>>  -Djava.nio.file.spi.DefaultFileSystemProvider=...
>> you have various bootstrapping issues.

>> With exploded modules, when trying to initialize the default file system, the
>> part of jigsaw that reads exploded modules uses path.toFile() that fails it
>> checks that the path belongs to the default file system which is not already
>> initialized
>> (see below for the whole stacktrace)

>> With modular jars, when trying to initialize the default file system, the
>> JarModuleReader also uses path.toFile(), leading to the same error

>> One way to solve that is to change the code in FileSystems.getDefault() to add a
>> nullcheck,
>>         FileSystem defaultFileSystem = DefaultFileSystemHolder.defaultFileSystem;
>>         if (jdk.internal.misc.VM.isBooted() && defaultFileSystem != null) {
>>             return defaultFileSystem;
>>         } else {
>>             return BuiltinFileSystemHolder.builtinFileSystem;
>>         }
>> Another solution is to change the code of jigsaw to only use the
>> builtinFileSystem, delaying the initialization of the default system which will
>> also solve the case where an application uses System.setProperty.

> I think the problem is that what FileSystems.getDefault() returns, changes over
> time. So you have Path instances associated with "builtin" filesystem,
> constructed before VM.isBooted() and after it is booted, Path instances are
> associated with what is configured to be the "default" filesystem. If those two
> differ and an instance, constructed before VM.isBooted() lives past the boot
> time and then .toFile() is called on such instance, we get
> "UnsupportedOperationException: Path not associated with default file
> system"...

> Maybe Alan could shed some light into this. As part of jigsaw implementation,
> the FileSystems.getDefault() was changed from:

> public static FileSystem getDefault() {
> return DefaultFileSystemHolder.defaultFileSystem;
> }

> to:

> public static FileSystem getDefault() {
> if (jdk.internal.misc.VM.isBooted()) {
> return DefaultFileSystemHolder.defaultFileSystem;
> } else {
> return BuiltinFileSystemHolder.builtinFileSystem;
> }
> }

> Probably because of early bootstrap issues. Module system needs FileSystem and
> custom FileSystem classes can not be loaded at that time yet.

> So I think that your second solution would be the right one. Jigsaw should only
> use the builtin filesystem explicitly, refraining from initializing the default
> filesystem. And Path.toFile() should allow creating a File from a Path in
> either case: whether Path is associated with builtin or default filesystem.
I think your right for the modular jars case, ModulePath store an array of Path created before the VM is considered as booted and consume them lazily :( 
I believe that replacing the path.toFile() by new File(path.toString()) will fix this issue. 

> Regards, Peter
Rémi 

>> cheers,
>> Rémi

>> Stacktrace with exploded modules:
>> Error: A JNI error has occurred, please check your installation and try again
>> Exception in thread "main" java.lang.Error:
>> java.lang.UnsupportedOperationException: Path not associated with default file
>> system.
>>	at
>> 	java.base/java.nio.file.FileSystems$DefaultFileSystemHolder.getDefaultProvider(FileSystems.java:139)
>>	at
>> 	java.base/java.nio.file.FileSystems$DefaultFileSystemHolder.access$100(FileSystems.java:100)
>>	at
>> 	java.base/java.nio.file.FileSystems$DefaultFileSystemHolder$1.run(FileSystems.java:109)
>>	at
>> 	java.base/java.nio.file.FileSystems$DefaultFileSystemHolder$1.run(FileSystems.java:107)
>> 	at java.base/java.security.AccessController.doPrivileged(Native Method)
>>	at
>> 	java.base/java.nio.file.FileSystems$DefaultFileSystemHolder.defaultFileSystem(FileSystems.java:107)
>>	at
>> 	java.base/java.nio.file.FileSystems$DefaultFileSystemHolder.<clinit>(FileSystems.java:101)
>> 	at java.base/java.nio.file.FileSystems.getDefault(FileSystems.java:188)
>> 	at java.base/java.nio.file.Path.toFile(Path.java:655)
>>	at
>> 	java.base/jdk.internal.module.ModuleReferences$JarModuleReader.newJarFile(ModuleReferences.java:229)
>>	at
>> 	java.base/jdk.internal.module.ModuleReferences$JarModuleReader.<init>(ModuleReferences.java:239)
>>	at
>> 	java.base/jdk.internal.module.ModuleReferences.lambda$newJarModule$0(ModuleReferences.java:96)
>>	at
>> 	java.base/jdk.internal.module.ModuleReferenceImpl.open(ModuleReferenceImpl.java:88)
>>	at
>> 	java.base/jdk.internal.loader.BuiltinClassLoader.createModuleReader(BuiltinClassLoader.java:953)
>>	at
>> 	java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1719)
>>	at
>> 	java.base/jdk.internal.loader.BuiltinClassLoader.moduleReaderFor(BuiltinClassLoader.java:945)
>>	at
>> 	java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:702)
>>	at
>> 	java.base/jdk.internal.loader.BuiltinClassLoader.findClassInModuleOrNull(BuiltinClassLoader.java:651)
>>	at
>> 	java.base/jdk.internal.loader.BuiltinClassLoader.findClass(BuiltinClassLoader.java:532)
>> 	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:585)
>> 	at java.base/java.lang.Class.forName(Class.java:447)
>>	at
>> 	java.base/sun.launcher.LauncherHelper.loadModuleMainClass(LauncherHelper.java:585)
>>	at
>> 	java.base/sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:523)
>> Caused by: java.lang.UnsupportedOperationException: Path not associated with
>> default file system.
>> 	at java.base/java.nio.file.Path.toFile(Path.java:658)
>>	at
>> 	java.base/jdk.internal.module.ModuleReferences$JarModuleReader.newJarFile(ModuleReferences.java:229)
>>	at
>> 	java.base/jdk.internal.module.ModuleReferences$JarModuleReader.<init>(ModuleReferences.java:239)
>>	at
>> 	java.base/jdk.internal.module.ModuleReferences.lambda$newJarModule$0(ModuleReferences.java:96)
>>	at
>> 	java.base/jdk.internal.module.ModuleReferenceImpl.open(ModuleReferenceImpl.java:88)
>>	at
>> 	java.base/jdk.internal.loader.BuiltinClassLoader.createModuleReader(BuiltinClassLoader.java:953)
>>	at
>> 	java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1719)
>>	at
>> 	java.base/jdk.internal.loader.BuiltinClassLoader.moduleReaderFor(BuiltinClassLoader.java:945)
>>	at
>> 	java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:702)
>>	at
>> 	java.base/jdk.internal.loader.BuiltinClassLoader.findClassInModuleOrNull(BuiltinClassLoader.java:651)
>>	at
>> 	java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:576)
>>	at
>> 	java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:550)
>>	at
>> 	java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:185)
>> 	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:473)
>> 	at java.base/java.lang.Class.forName0(Native Method)
>> 	at java.base/java.lang.Class.forName(Class.java:374)
>>	at
>> 	java.base/java.nio.file.FileSystems$DefaultFileSystemHolder.getDefaultProvider(FileSystems.java:129)
>> 	... 22 more

>> StackTrace with modular jars:
>> Error: A JNI error has occurred, please check your installation and try again
>> Exception in thread "main" java.lang.Error:
>> java.lang.UnsupportedOperationException: Path not associated with default file
>> system.
>>	at
>> 	java.base/java.nio.file.FileSystems$DefaultFileSystemHolder.getDefaultProvider(FileSystems.java:139)
>>	at
>> 	java.base/java.nio.file.FileSystems$DefaultFileSystemHolder.access$100(FileSystems.java:100)
>>	at
>> 	java.base/java.nio.file.FileSystems$DefaultFileSystemHolder$1.run(FileSystems.java:109)
>>	at
>> 	java.base/java.nio.file.FileSystems$DefaultFileSystemHolder$1.run(FileSystems.java:107)
>> 	at java.base/java.security.AccessController.doPrivileged(Native Method)
>>	at
>> 	java.base/java.nio.file.FileSystems$DefaultFileSystemHolder.defaultFileSystem(FileSystems.java:107)
>>	at
>> 	java.base/java.nio.file.FileSystems$DefaultFileSystemHolder.<clinit>(FileSystems.java:101)
>> 	at java.base/java.nio.file.FileSystems.getDefault(FileSystems.java:188)
>> 	at java.base/java.nio.file.Path.toFile(Path.java:655)
>>	at
>> 	java.base/jdk.internal.module.ModuleReferences$JarModuleReader.newJarFile(ModuleReferences.java:229)
>>	at
>> 	java.base/jdk.internal.module.ModuleReferences$JarModuleReader.<init>(ModuleReferences.java:239)
>>	at
>> 	java.base/jdk.internal.module.ModuleReferences.lambda$newJarModule$0(ModuleReferences.java:96)
>>	at
>> 	java.base/jdk.internal.module.ModuleReferenceImpl.open(ModuleReferenceImpl.java:88)
>>	at
>> 	java.base/jdk.internal.loader.BuiltinClassLoader.createModuleReader(BuiltinClassLoader.java:953)
>>	at
>> 	java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1719)
>>	at
>> 	java.base/jdk.internal.loader.BuiltinClassLoader.moduleReaderFor(BuiltinClassLoader.java:945)
>>	at
>> 	java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:702)
>>	at
>> 	java.base/jdk.internal.loader.BuiltinClassLoader.findClassInModuleOrNull(BuiltinClassLoader.java:651)
>>	at
>> 	java.base/jdk.internal.loader.BuiltinClassLoader.findClass(BuiltinClassLoader.java:532)
>> 	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:585)
>> 	at java.base/java.lang.Class.forName(Class.java:447)
>>	at
>> 	java.base/sun.launcher.LauncherHelper.loadModuleMainClass(LauncherHelper.java:585)
>>	at
>> 	java.base/sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:523)
>> Caused by: java.lang.UnsupportedOperationException: Path not associated with
>> default file system.
>> 	at java.base/java.nio.file.Path.toFile(Path.java:658)
>>	at
>> 	java.base/jdk.internal.module.ModuleReferences$JarModuleReader.newJarFile(ModuleReferences.java:229)
>>	at
>> 	java.base/jdk.internal.module.ModuleReferences$JarModuleReader.<init>(ModuleReferences.java:239)
>>	at
>> 	java.base/jdk.internal.module.ModuleReferences.lambda$newJarModule$0(ModuleReferences.java:96)
>>	at
>> 	java.base/jdk.internal.module.ModuleReferenceImpl.open(ModuleReferenceImpl.java:88)
>>	at
>> 	java.base/jdk.internal.loader.BuiltinClassLoader.createModuleReader(BuiltinClassLoader.java:953)
>>	at
>> 	java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1719)
>>	at
>> 	java.base/jdk.internal.loader.BuiltinClassLoader.moduleReaderFor(BuiltinClassLoader.java:945)
>>	at
>> 	java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:702)
>>	at
>> 	java.base/jdk.internal.loader.BuiltinClassLoader.findClassInModuleOrNull(BuiltinClassLoader.java:651)
>>	at
>> 	java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:576)
>>	at
>> 	java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:550)
>>	at
>> 	java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:185)
>> 	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:473)
>> 	at java.base/java.lang.Class.forName0(Native Method)
>> 	at java.base/java.lang.Class.forName(Class.java:374)
>>	at
>> 	java.base/java.nio.file.FileSystems$DefaultFileSystemHolder.getDefaultProvider(FileSystems.java:129)
>> 	... 22 more


More information about the jigsaw-dev mailing list