FULL PRODUCT VERSION :
java version "1.8.0_102"
Java(TM) SE Runtime Environment (build 1.8.0_102-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux rrosenbl-ld1 2.6.32-504.el6.x86_64 #1 SMP Tue Sep 16 01:56:35 EDT 2014 x86_64 x86_64 x86_64 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
the implementation of InflaterInputStream.available():
   public int available() throws IOException {
        ensureOpen();
        if (reachEOF) {
            return 0;
        } else {
            return 1;
        }
    }
will return 1 in situations where the underlying inflater is actually finished, but has not been read() from (so no -1 seen). it seems that the condition in the method can be updated to :
   public int available() throws IOException {
        ensureOpen();
        if (reachEOF || inf.finished()) {
            return 0;
        } else {
            return 1;
        }
    }
such that available() will return 0 correctly (instead of returning available = 1 and the subsequent read() returning -1).
the impact of this is that if such an inflater stream is wrapped in a DataInputStream, the following code cannot work:
InflaterStream underlying = ...;
DataInsputStream decorator = ... //wrap underlying
while (underlying.available() > 0) {
   //read something via decorator
}
with the current code the only option is to catch an EOF (thrown by DataInputStream in response to reading -1 as part of readFully())
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
the following code will reproduce the issue:
    public static void main(String[] args) throws Exception {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        GZIPOutputStream zos = new GZIPOutputStream(baos);
        zos.write("some content".getBytes(Charset.forName("UTF-8")));
        zos.close();
        byte[] zippedBlob = baos.toByteArray();
        GZIPInputStream zis = new GZIPInputStream(new ByteArrayInputStream(zippedBlob));
        while (zis.available() > 0) {
            int read = zis.read();
            if (read == -1) {
                System.err.println("you lied to me");
            }
        }
    }
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
code should run with nothing printed to system.err
ACTUAL -
message printed to System.err indicating available() returned a positive value yet the subsequent read() returned -1
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
    public static void main(String[] args) throws Exception {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        GZIPOutputStream zos = new GZIPOutputStream(baos);
        zos.write("some content".getBytes(Charset.forName("UTF-8")));
        zos.close();
        byte[] zippedBlob = baos.toByteArray();
        GZIPInputStream zis = new GZIPInputStream(new ByteArrayInputStream(zippedBlob));
        while (zis.available() > 0) {
            int read = zis.read();
            if (read == -1) {
                System.err.println("you lied to me");
            }
        }
    }
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
forced to catch the EOFException throws by DataInputStream in response to -1. this has a performance impact on my code.