JDK-8198274 : ZipInputStream.read() redefines semantics of InputStream.read()
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util.jar
  • Affected Version: 1.1,8,9,10
  • Priority: P4
  • Status: Resolved
  • Resolution: Not an Issue
  • OS: windows
  • CPU: x86_64
  • Submitted: 2018-02-09
  • Updated: 2018-03-14
  • Resolved: 2018-02-16
Description
FULL PRODUCT VERSION :
java version "9.0.4"
Java(TM) SE Runtime Environment (build 9.0.4+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.4+11, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 10.0.16299.192]

A DESCRIPTION OF THE PROBLEM :
InputStream.read() methods are documented to read bytes from the input stream.  ZipInputStream.read() methods are documented to read bytes from the "current entry" in the JAR file.

InputStream is passed to methods like java.nio.file.Files.copy() which expect to read all of the bytes in the InputStream.  

sun.net.www.protocol.jar.URLJarFile.retrieve(), for instance, expects to copy a JAR file from a URL to a temporary file this way.  When the URL's InputStream is a ZipInputStream, the temporary file has a length of zero because Files.copy() expects InputStream.read() to read the entire file, but ZipInputStream.read() returns -1 because there is no current entry.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
ZipInputStream zis = new ZipInputStream(new FileInputStream("test.zip"));
Path tmpFile = Files.createTempFile("jar_cache", null);
Files.copy(zis, tmpFile, StandardCopyOption.REPLACE_EXISTING);
System.out.println("Length of temp file: " + tmpFile.toFile().length());


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Length of temp file should be the length of the "test.zip" file.
ACTUAL -
Length of temp file is 0.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
ZipInputStream zis = new ZipInputStream(new FileInputStream("test.zip"));
Path tmpFile = Files.createTempFile("jar_cache", null);
Files.copy(zis, tmpFile, StandardCopyOption.REPLACE_EXISTING);
System.out.println("Length of temp file: " + tmpFile.toFile().length());

---------- END SOURCE ----------


Comments
This is how ZipInputStream is designed, implemented and supposed to behave.
16-02-2018

To reproduce the issue, run the attached test case. JDK 8u161- Fail JDK 9.0.4+11 - Fail JDK 10-ea+39 - Fail Output : Length of temp file: 0
16-02-2018

This is how the ZipInputStream was designed in JDK 1.1.
16-02-2018