On 04/22/2017 08:10 PM, fo...@univ-mlv.fr wrote:
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.
Or this might work too:
http://cr.openjdk.java.net/~plevart/jdk9-dev/Path.toFile/webrev.01/
A variant of this might be for FileSystems.getDefault() to start
returning the custom default filesystem as soon as initLevel reaches 2
(after module system is initialized). This might allow custom default
file system to be effective even before the VM is fully booted (for
custom security manager or system class loader or java agent to already
take advantage of it). But that probably would mean that the custom
default filesystem loading logic would have to be modified in order to
cope with system class loader not being setup already - it could use the
builtin app class loader for locating and loading the classes...
Do you happen to have a custom default filesystem to try this with?
Regards, Peter
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