<div dir="ltr">
Hi,<div class="gmail_quote"><div dir="ltr"><div><br></div><div>When reading from a zip file on the disk, <span style="font-family:monospace">ZipFileSystem</span> uses a <span style="font-family:monospace">SeekableByteChannel</span>
internally to read from the zip file. Unfortunately, this channel is
interruptible, and therefore a single thread interruption while reading
from a <span style="font-family:monospace">ZipPath</span> will make the entire ZipFS unusable. This is problematic for long-lived <span style="font-family:monospace">ZipFileSystem</span><span style="font-family:arial,sans-serif">s</span> that can be used by multiple threads. I suppose that this is a bug?<br><div><br></div><div>One workaround is to use deep reflection
to call `setUninterruptible()` on the underlying file channel if
supported, however I am not sure of the side-effects. It does seem to
fix this issue though.</div><div><br></div><div>
I couldn't get <a href="https://bugreport.java.com" target="_blank">https://bugreport.java.com</a> to work so I'm posting this here instead. Thanks in advance.
</div>
</div><div><br></div><div>Regards,</div><div>Bruno Ploumhans<br>
</div><div><br></div><div>PS: Here is a snippet that consistently
reproduces the issue on my machine: it crashes on the second read
attempt with a `ClosedChannelException`.<br></div><div><br></div><div>import java.io.*;<br>import java.nio.file.*;<br>import java.util.zip.*;<br><br>public class nio_repro {<br> public static void main(String[] args) throws Exception {<br> // Create a dummy test.zip<br> File f = new File("test.zip");<br> try (ZipOutputStream out = new ZipOutputStream(new FileOutputStream(f))) {<br> ZipEntry e = new ZipEntry("entry1.txt");<br> out.putNextEntry(e);<br> <br> byte[] data1 = "Text1".repeat(100000000).getBytes(); // Large entry so it takes time to read<br> out.write(data1, 0, data1.length);<br> out.closeEntry();<br> }<br><br> // Open zip FS<br> FileSystem fs = FileSystems.newFileSystem(f.toPath());<br> // Start reading on second thread<br> Thread secondThread = Thread.ofPlatform().start(() -> {<br> try {<br> byte[] contents = Files.readAllBytes(fs.getPath("entry1.txt"));<br> } catch (IOException ex) {<br> throw new UncheckedIOException(ex);<br> }<br> });<br> Thread.sleep(1);<br> // Interrupt read<br> secondThread.interrupt();<br> // Try to read again - this should crash with a ClosedChannelException<br> byte[] contents = Files.readAllBytes(fs.getPath("entry1.txt"));<br><br> System.out.println("Successfully read " + contents.length + " bytes.");<br> }<br>}</div></div>
</div>
</div>