(Originally uncovered by Volkan [~vyazici])
The following code:
final Path zipFile = ...; // Path to a ZIP file
final URI zipFSURI = URI.create("jar:file:" + zipFile.toAbsolutePath());
// open it using a FileSystem
try (FileSystem zipfs = FileSystems.newFileSystem(zipFSURI, Map.of())) {
// now create a ByteChannel out of that large entry
ByteChannel bc = Files.newByteChannel(zipfs.getPath(ENTRY_NAME), Set.of());
...
for a Path that represents a large entry in a ZIP file, can lead to an OutOfMemory error like:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.base/java.io.InputStream.readNBytes(InputStream.java:407)
at java.base/java.io.InputStream.readAllBytes(InputStream.java:348)
at jdk.zipfs/jdk.nio.zipfs.ZipFileSystem.newByteChannel(ZipFileSystem.java:952)
at jdk.zipfs/jdk.nio.zipfs.ZipPath.newByteChannel(ZipPath.java:857)
at jdk.zipfs/jdk.nio.zipfs.ZipFileSystemProvider.newByteChannel(ZipFileSystemProvider.java:244)
at java.base/java.nio.file.Files.newByteChannel(Files.java:357)
at TestZipFS.main(TestZipFS.java:48)
This is because of the implementation in ZipFileSystem which reads into memory, the entire content of the ZIP entry when the newByteChannel() method is called. Larger the entry, higher the chances of the OutOfMemoryError.
A reproducer is attached which can be run as:
"java -Xmx256M TestZipFS.java"
The following code:
final Path zipFile = ...; // Path to a ZIP file
final URI zipFSURI = URI.create("jar:file:" + zipFile.toAbsolutePath());
// open it using a FileSystem
try (FileSystem zipfs = FileSystems.newFileSystem(zipFSURI, Map.of())) {
// now create a ByteChannel out of that large entry
ByteChannel bc = Files.newByteChannel(zipfs.getPath(ENTRY_NAME), Set.of());
...
for a Path that represents a large entry in a ZIP file, can lead to an OutOfMemory error like:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.base/java.io.InputStream.readNBytes(InputStream.java:407)
at java.base/java.io.InputStream.readAllBytes(InputStream.java:348)
at jdk.zipfs/jdk.nio.zipfs.ZipFileSystem.newByteChannel(ZipFileSystem.java:952)
at jdk.zipfs/jdk.nio.zipfs.ZipPath.newByteChannel(ZipPath.java:857)
at jdk.zipfs/jdk.nio.zipfs.ZipFileSystemProvider.newByteChannel(ZipFileSystemProvider.java:244)
at java.base/java.nio.file.Files.newByteChannel(Files.java:357)
at TestZipFS.main(TestZipFS.java:48)
This is because of the implementation in ZipFileSystem which reads into memory, the entire content of the ZIP entry when the newByteChannel() method is called. Larger the entry, higher the chances of the OutOfMemoryError.
A reproducer is attached which can be run as:
"java -Xmx256M TestZipFS.java"
- caused by
-
JDK-8034802 (zipfs) newFileSystem throws UOE when the zip file is located in a custom file system
-
- Closed
-