-
Bug
-
Resolution: Unresolved
-
P4
-
8, 11, 17, 18, 19, 20
-
generic
-
generic
A DESCRIPTION OF THE PROBLEM :
If the source zip file has been deleted, ZipFileSystem.close() fails and the internal map jdk.nio.zipfs.ZipFileSystemProvider.filesystems is not properly cleared.
Even if the source file is recreated, it is not possible to use ZipFileSystem later on this path.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Create a jar file on the file system
2. Open a FileSystems.newFileSystem(new URI("jar:..."))
3. Delete the source file in the file system
4. Close the jar FileSystem
5. Recreate the source file in the file system
6. Open a new FileSystems.newFileSystem(new URI("jar:..."))
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
At step 4, FileSystem.close() should not throw an exception
At step 6, we should be able to create new jar FileSystem without exception
ACTUAL -
- step 4, FileSystem.close() fails with a NoSuchFileException
- step 6 throws a FileSystemAlreadyExistsException, this path is never usable.
---------- BEGIN SOURCE ----------
import java.io.OutputStream;
import java.net.URI;
import java.nio.file.*;
import java.util.Collections;
import java.util.zip.ZipOutputStream;
public class BugZipFileSystem {
public static void main(String[] args) {
try {
System.out.println("Java version: "+System.getProperty("java.runtime.version"));
//1. Create a zip file
Path zipFile = Files.createTempFile("buZipFilSystem", ".zip");
try (OutputStream out = Files.newOutputStream(zipFile)) {
new ZipOutputStream(out).close();
}
URI zipUri = new URI("jar:" + zipFile.toUri());
//2. Instantiate a ZipFileSystem
FileSystem zipFs = FileSystems.newFileSystem(zipUri, Collections.EMPTY_MAP);
//3. Delete the source file
Files.delete(zipFile);
//4. Close the ZipFileSystem
try {
zipFs.close();
} catch (NoSuchFileException e) {
System.out.println("zipFs.close() throw NoSuchFileException: not sure it was a good thing!");
System.out.println("The internal Map jdk.nio.zipfs.ZipFileSystemProvider.filesystems is not correctly cleared");
}
//5. Recreate the zip
try (OutputStream out = Files.newOutputStream(zipFile)) {
new ZipOutputStream(out).close();
}
//6. It is now impossible to re-use the zipFs or instantiate a new one
zipFs = FileSystems.getFileSystem(zipUri);
if (!zipFs.isOpen()) System.out.println("zipFs is always internally referenced but closed and not usable");
try {
zipFs = FileSystems.newFileSystem(zipUri, Collections.EMPTY_MAP);
} catch (Exception e) {
System.out.println("A new ZipFs can not be instanciated because it is referenced in the internal map jdk.nio.zipfs.ZipFileSystemProvider.filesystems: " + e);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Before calling ZipFileSystem.close() check if the file has been deleted and recreate it temporarily (along with its parent folders)
FREQUENCY : always
If the source zip file has been deleted, ZipFileSystem.close() fails and the internal map jdk.nio.zipfs.ZipFileSystemProvider.filesystems is not properly cleared.
Even if the source file is recreated, it is not possible to use ZipFileSystem later on this path.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Create a jar file on the file system
2. Open a FileSystems.newFileSystem(new URI("jar:..."))
3. Delete the source file in the file system
4. Close the jar FileSystem
5. Recreate the source file in the file system
6. Open a new FileSystems.newFileSystem(new URI("jar:..."))
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
At step 4, FileSystem.close() should not throw an exception
At step 6, we should be able to create new jar FileSystem without exception
ACTUAL -
- step 4, FileSystem.close() fails with a NoSuchFileException
- step 6 throws a FileSystemAlreadyExistsException, this path is never usable.
---------- BEGIN SOURCE ----------
import java.io.OutputStream;
import java.net.URI;
import java.nio.file.*;
import java.util.Collections;
import java.util.zip.ZipOutputStream;
public class BugZipFileSystem {
public static void main(String[] args) {
try {
System.out.println("Java version: "+System.getProperty("java.runtime.version"));
//1. Create a zip file
Path zipFile = Files.createTempFile("buZipFilSystem", ".zip");
try (OutputStream out = Files.newOutputStream(zipFile)) {
new ZipOutputStream(out).close();
}
URI zipUri = new URI("jar:" + zipFile.toUri());
//2. Instantiate a ZipFileSystem
FileSystem zipFs = FileSystems.newFileSystem(zipUri, Collections.EMPTY_MAP);
//3. Delete the source file
Files.delete(zipFile);
//4. Close the ZipFileSystem
try {
zipFs.close();
} catch (NoSuchFileException e) {
System.out.println("zipFs.close() throw NoSuchFileException: not sure it was a good thing!");
System.out.println("The internal Map jdk.nio.zipfs.ZipFileSystemProvider.filesystems is not correctly cleared");
}
//5. Recreate the zip
try (OutputStream out = Files.newOutputStream(zipFile)) {
new ZipOutputStream(out).close();
}
//6. It is now impossible to re-use the zipFs or instantiate a new one
zipFs = FileSystems.getFileSystem(zipUri);
if (!zipFs.isOpen()) System.out.println("zipFs is always internally referenced but closed and not usable");
try {
zipFs = FileSystems.newFileSystem(zipUri, Collections.EMPTY_MAP);
} catch (Exception e) {
System.out.println("A new ZipFs can not be instanciated because it is referenced in the internal map jdk.nio.zipfs.ZipFileSystemProvider.filesystems: " + e);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Before calling ZipFileSystem.close() check if the file has been deleted and recreate it temporarily (along with its parent folders)
FREQUENCY : always