JBR-8123 NPE because FileSystems.getDefault() is null with -Djava.util.zip.use.nio.for.zip.file.access=true

This commit is contained in:
Maxim Kartashev
2025-01-14 13:26:58 +04:00
committed by jbrbot
parent 1c23891c21
commit 0adaf1a172
2 changed files with 27 additions and 0 deletions

View File

@@ -46,6 +46,7 @@ import java.nio.channels.Channel;
import java.nio.channels.spi.SelectorProvider;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.file.FileSystems;
import java.security.ProtectionDomain;
import java.util.List;
import java.util.Locale;
@@ -1966,6 +1967,16 @@ public final class System {
// set TCCL
Thread.currentThread().setContextClassLoader(scl);
if (Boolean.getBoolean("java.util.zip.use.nio.for.zip.file.access")
&& System.getProperty("java.nio.file.spi.DefaultFileSystemProvider") != null) {
// Make sure the custom file system(s) are loaded using the "standard" ZipFile operating mode
// rather than the one that forwards to NIO. The latter will use the file system that is being loaded to
// try to load files, which will result in an NPE from FileSystems.getDefault().
// Calling FileSystems.getDefault() here bypasses that because the NIO operating mode of ZipFile only
// activates at init level 4.
FileSystems.getDefault();
}
// system is fully initialized
VM.initLevel(4);
}

View File

@@ -218,6 +218,22 @@ class SetDefaultProvider {
TESTAPP_MAIN);
}
/**
* Test the file system provider located in a jar with
* -Djava.util.zip.use.nio.for.zip.file.access=true
* that makes ZipFile use NIO to read the jar.
*/
@Test
void testClassPathWithFileSystemProviderJarAndNioForZipFile() throws Exception {
String testClasses = System.getProperty("test.classes");
String fspJar = createJar("testfsp.jar", TESTFSP_CLASSES);
String appJar = createJar("testapp.jar", TESTAPP_CLASSES);
exec(SET_DEFAULT_FSP, "-Djava.util.zip.use.nio.for.zip.file.access=true",
"-cp", ofClasspath(fspJar, appJar, testClasses), TESTAPP_MAIN);
}
/**
* Returns the directory containing the classes for the given module.
*/