javac doesn't work with jar files with >64k entries

Martin Buchholz martinrb at
Wed Nov 7 09:49:21 PST 2012

Hi compiler folk,

You don't like someone else's zip implementation, cuz it's too SLOOOW, so
you write your own.  Now you have two problems.

 int entryCount = get2ByteLittleEndian(zipDir, 0);

The ZIP specification includes ENDTOT, a field that contains the number of
entries in a zip file.
Unfortunately, all high quality zip implementations ignore this field (or
more accurately, treat it as a hint).
Read zip_util.c and be enlightened:

    /* Initialize zip file data structures based on the total number
     * of central directory entries as stored in ENDTOT.  Since this
     * is a 2-byte field, but we (and other zip implementations)
     * support approx. 2**31 entries, we do not trust ENDTOT, but
     * treat it only as a strong hint.  When we call ourselves

This needs fixing.  Since you are iterating through the CEN already, just
stop when you hit the end header, whose location you know.

You can imagine the painful frustrating failure mode of javac starting to
very mysteriously fail as the size of an input jar creeps over 64k entries.

jdk6 javac has the same problem, but disabling the "optimized" zip
implementation requires different mechanisms.

The sources could be more readable.  Probably your source code is haunted
by Phil Katz' ghost because you are using hex constants instead of 'P' and
'K' as Phil Katz intended.

                        !(endbuf[i] == 0x50 &&
                        endbuf[i + 1] == 0x4b &&

You get points for noticing that the input zip file is in ZIP64 format

                    if (sz < 0 || get2ByteLittleEndian(zipDir, 0) ==
0xffff) {
                        throw new ZipFormatException("detected a zip64

but the only proper reaction is to either add full ZIP64 support or
fallback to the "unoptimized but actually working" implementation.

-------------- next part --------------
An HTML attachment was scrubbed...

More information about the compiler-dev mailing list