Question

I am extracting a ZIP file in java:

ZipFile zipFile = new ZipFile(theZipFile);
  Enumeration<? extends ZipEntry> zipEntries = zipFile.entries();
    while(zipEntries.hasMoreElements()){
      ZipEntry entry = zipEntries.nextElement(); /// <---Nullpointer exception happens here
  }

The code execution past while(zipEntries.hasMoreElements()) but failed at extracting a ZipEntry.

It’s strange that hasMoreElements returns true, but null pointer occurs when trying to get elements out.

The exception is from within the ZipFile class from JDK lib, which I can not see local variables in debugger, so how do I find out what is wrong with the Zip file?

Edit: Stack trace:

java.lang.NullPointerException
    at java.util.zip.ZipFile.getZipEntry(ZipFile.java:529)
    at java.util.zip.ZipFile.access$900(ZipFile.java:56)
    at java.util.zip.ZipFile$1.nextElement(ZipFile.java:511)
    at java.util.zip.ZipFile$1.nextElement(ZipFile.java:481)
Was it helpful?

Solution

Here is the getZipEntry method (as of 1.7.0_10):

private ZipEntry getZipEntry(String name, long jzentry) {
    ZipEntry e = new ZipEntry();
    e.flag = getEntryFlag(jzentry);  // get the flag first
    if (name != null) {
        e.name = name;
    } else {
        byte[] bname = getEntryBytes(jzentry, JZENTRY_NAME);
        if (!zc.isUTF8() && (e.flag & EFS) != 0) {
            e.name = zc.toStringUTF8(bname, bname.length);
        } else {
            e.name = zc.toString(bname, bname.length);      // Line 529
        }
    }
    /* snip */
    return e;
}

The only reason a NullPointerException would be thrown on this line would be if e, zc, or bname were null.

e cannot be null because it is clearly instantiated in this method.

zc cannot be null:

public ZipFile(File file, int mode, Charset charset) throws IOException
{
    /* snip */
    this.zc = ZipCoder.get(charset);
    /* snip */
}

static ZipCoder get(Charset charset) {
    return new ZipCoder(charset);
}

Which means that bname must be null, which is going to be pretty hard to debug. getEntryBytes is a native method:

private static native byte[] getEntryBytes(long jzentry, int type);

This is how I would proceed:

  • Figure out if it's that particular zip file or all zip files. If it's that particular zip file, try remaking it.
  • Update your version of Java, it's possible that there was a bug with getEntryBytes that was fixed
  • Submit a bug report to Oracle

OTHER TIPS

I had same issue recently and so I compared JDK 1.6 and 1.7 related zip source code.

The real reason is jdk 1.6 will initial zipEntry with jzentry by constructor like this:

ZipEntry ze = new ZipEntry(jzentry);

ZipEntry(long jzentry) {
    initFields(jzentry);
}

but in jdk 1.7 we can see it use

private ZipEntry getZipEntry(String name, long jzentry) {
    ZipEntry e = new ZipEntry(); // it did not use jzentry initial it

When some jar file have empty entry it will throw exception.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top