如何调试库代码中发生的NullPointerException?

时间:2013-02-21 02:33:51

标签: java nullpointerexception zipfile

我在java中提取ZIP文件:

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

代码执行超过while(zipEntries.hasMoreElements())但在提取ZipEntry时失败。

奇怪的是hasMoreElements返回true,但在尝试获取元素时会出现空指针。

异常来自JDK lib的ZipFile类,我在调试器中看不到局部变量,所以如何找出Zip文件有什么问题?

编辑: 堆栈跟踪:

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)

2 个答案:

答案 0 :(得分:3)

以下是getZipEntry方法(截至2010年10月1日):

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;
}

如果NullPointerExceptionezc bnamenulle将被投放到此行的唯一原因。

null不能为zc,因为它在此方法中已明确实例化。

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); }

bname

这意味着null必须是getEntryBytes,这将非常难以调试。 nativeprivate static native byte[] getEntryBytes(long jzentry, int type); 方法:

getEntryBytes

这就是我要继续下去的方式:

  • 弄清楚它是特定的zip文件还是所有zip文件。如果是特定的zip文件,请尝试重新制作它。
  • 更新您的Java版本,可能是{{1}}存在修复的错误
  • 向Oracle提交错误报告

答案 1 :(得分:0)

我最近遇到了同样的问题,因此我比较了 JDK 1.6 1.7 相关的 zip源代码

真正的原因 jdk 1.6 jentry 初始 zipEntry 构造函数 像这样:

ZipEntry ze = new ZipEntry(jzentry);

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

但是在 jdk 1.7 中我们可以看到它使用

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

当某个 jar 文件有空条目时,它会抛出异常。