奇怪的 Java 异常 java.util.zip.ZipException: 打开 zip 文件时出错

Strange Java exception java.util.zip.ZipException: error in opening zip file

我编写了 JMTI 代理以从应用中获取异常:

#include <jvmti.h>
#include <string.h>

void printStackTrace(JNIEnv* env, jobject exception) {
    jclass throwable_class = (*env).FindClass("java/lang/Throwable");
    jmethodID print_method = (*env).GetMethodID(throwable_class, "printStackTrace", "()V");
    (*env).CallVoidMethod(exception, print_method);
}

static void frameToString(jvmtiEnv *jvmti, jvmtiFrameInfo *finfo)
{
    jvmtiError           error;
    jclass               klass;
    char                *signature;
    char                *methodname;
    char                *methodsig;
    jboolean             isNative;
    char                *filename;
    int                  lineCount;
    jvmtiLineNumberEntry*lineTable;
    int                  lineNumber;

    /* Initialize defaults */
    klass      = NULL;
    signature  = NULL;
    methodname = NULL;
    methodsig  = NULL;
    isNative   = JNI_FALSE;
    filename   = NULL;
    lineCount  = 0;
    lineTable  = NULL;
    lineNumber = 0;

    /* Get jclass object for the jmethodID */
    error = (*jvmti).GetMethodDeclaringClass(finfo->method, &klass);

    /* Get the class signature */
    error = (*jvmti).GetClassSignature(klass, &signature, NULL);


    /* Get the name and signature for the method */
    error = (*jvmti).GetMethodName(finfo->method, &methodname, &methodsig, NULL);


    /* Check to see if it's a native method, which means no lineNumber */
    error = (*jvmti).IsMethodNative(finfo->method, &isNative);


    /* Get source file name */
    error = (*jvmti).GetSourceFileName(klass, &filename);
    if ( error != JVMTI_ERROR_NONE && error != JVMTI_ERROR_ABSENT_INFORMATION ) {
        printf("%d \n", error);
    }

    /* Get lineNumber if we can */
    if ( !isNative ) {
        int i;

        /* Get method line table */
        error = (*jvmti).GetLineNumberTable(finfo->method, &lineCount, &lineTable);
        if ( error == JVMTI_ERROR_NONE ) {
            /* Search for line */
            lineNumber = lineTable[0].line_number;
            for ( i = 1 ; i < lineCount ; i++ ) {
                if ( finfo->location < lineTable[i].start_location ) {
                    break;
                }
                lineNumber = lineTable[i].line_number;
            }
        }
    }

    /* Create string for this frame location.
     *    NOTE: These char* quantities are mUTF (Modified UTF-8) bytes
     *          and should actually be converted to the default system
     *          character encoding. Sending them to things like
     *          printf() without converting them is actually an I18n
     *          (Internationalization) error.
     */
    printf("%s.%s@%d[%s:%d]\n", signature, methodname, (int)finfo->location, filename, lineNumber);

//    /* Free up JVMTI space allocated by the above calls */
//    deallocate(jvmti, signature);
//    deallocate(jvmti, methodname);
//    deallocate(jvmti, methodsig);
//    deallocate(jvmti, filename);
//    deallocate(jvmti, lineTable);
}

void JNICALL ExceptionCallback(jvmtiEnv* jvmti, JNIEnv* env, jthread thread,
                               jmethodID method, jlocation location, jobject exception,
                               jmethodID catch_method, jlocation catch_location) {
//    int count;
//    int line_number = 0;
//    int i;
//    char* class_name;
//    char* method_name;

    jvmtiFrameInfo frames[10];
    jint count;
    jint frame_count;

//    jclass exception_class = (*env).GetObjectClass(exception);
//    (*jvmti).GetClassSignature(exception_class, &class_name, NULL);
//    (*jvmti).GetMethodName(method, &method_name, NULL, NULL);
//    (*jvmti).GetSourceFileName()
//
//    jvmtiLineNumberEntry *location_table;
//    (*jvmti).GetLineNumberTable(method, &count, &location_table);
//    for (i = 0; i < count - 1; i++)
//    {
//        jvmtiLineNumberEntry entry1 = location_table[i];
//        jvmtiLineNumberEntry entry2 = location_table[i+1];
//        if (location >= entry1.start_location && location < entry2.start_location)
//        {
//            line_number = entry1.line_number;
//            break;
//        }
//    }
//    if (location >= location_table[count-1].start_location)
//    {
//        line_number = location_table[count-1].line_number;
//    }
//
//    printf("%s %d \n", class_name, line_number);

    (*jvmti).GetStackTrace(thread, (jint)0, (jint)10, (jvmtiFrameInfo *)&frames, &count);
    frameToString(jvmti, frames);
    printStackTrace(env, exception);
}

JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM* vm, char* options, void* reserved) {
    jvmtiEnv* jvmti;
    jvmtiEventCallbacks callbacks;
    jvmtiCapabilities capabilities;

    (*vm).GetEnv((void**)&jvmti, JVMTI_VERSION_1_0);

    memset(&capabilities, 0, sizeof(capabilities));
    capabilities.can_generate_exception_events = 1;
    capabilities.can_get_line_numbers = 1;
    capabilities.can_get_source_file_name = 1;
//    capabilities.can_suspend = 1;
    (*jvmti).AddCapabilities(&capabilities);

    memset(&callbacks, 0, sizeof(callbacks));
    callbacks.Exception = ExceptionCallback;
    (*jvmti).SetEventCallbacks(&callbacks, sizeof(callbacks));
    (*jvmti).SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_EXCEPTION, NULL);

    return 0;
}

并在测试之后。 A 有奇怪的异常:

java.util.zip.ZipException: error in opening zip file
    at java.util.zip.ZipFile.open(Native Method)
    at java.util.zip.ZipFile.<init>(ZipFile.java:219)
    at java.util.zip.ZipFile.<init>(ZipFile.java:149)
    at java.util.jar.JarFile.<init>(JarFile.java:166)
    at java.util.jar.JarFile.<init>(JarFile.java:103)
    at sun.misc.URLClassPath$JarLoader.getJarFile(URLClassPath.java:893)
    at sun.misc.URLClassPath$JarLoader.access0(URLClassPath.java:756)
    at sun.misc.URLClassPath$JarLoader.run(URLClassPath.java:838)
    at sun.misc.URLClassPath$JarLoader.run(URLClassPath.java:831)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.misc.URLClassPath$JarLoader.ensureOpen(URLClassPath.java:830)
    at sun.misc.URLClassPath$JarLoader.<init>(URLClassPath.java:803)
    at sun.misc.URLClassPath.run(URLClassPath.java:530)
    at sun.misc.URLClassPath.run(URLClassPath.java:520)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.misc.URLClassPath.getLoader(URLClassPath.java:519)
    at sun.misc.URLClassPath.getLoader(URLClassPath.java:492)
    at sun.misc.URLClassPath.getNextLoader(URLClassPath.java:457)
    at sun.misc.URLClassPath.getResource(URLClassPath.java:211)
    at java.net.URLClassLoader.run(URLClassLoader.java:365)
    at java.net.URLClassLoader.run(URLClassLoader.java:362)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:411)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:304)
    at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:401)
java.security.PrivilegedActionException: java.util.zip.ZipException: error in opening zip file
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.misc.URLClassPath$JarLoader.ensureOpen(URLClassPath.java:830)
    at sun.misc.URLClassPath$JarLoader.<init>(URLClassPath.java:803)
    at sun.misc.URLClassPath.run(URLClassPath.java:530)
    at sun.misc.URLClassPath.run(URLClassPath.java:520)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.misc.URLClassPath.getLoader(URLClassPath.java:519)
    at sun.misc.URLClassPath.getLoader(URLClassPath.java:492)
    at sun.misc.URLClassPath.getNextLoader(URLClassPath.java:457)
    at sun.misc.URLClassPath.getResource(URLClassPath.java:211)
    at java.net.URLClassLoader.run(URLClassLoader.java:365)
    at java.net.URLClassLoader.run(URLClassLoader.java:362)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:411)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:304)
    at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:401)
Caused by: java.util.zip.ZipException: error in opening zip file
    at java.util.zip.ZipFile.open(Native Method)
    at java.util.zip.ZipFile.<init>(ZipFile.java:219)
    at java.util.zip.ZipFile.<init>(ZipFile.java:149)
    at java.util.jar.JarFile.<init>(JarFile.java:166)
    at java.util.jar.JarFile.<init>(JarFile.java:103)
    at sun.misc.URLClassPath$JarLoader.getJarFile(URLClassPath.java:893)
    at sun.misc.URLClassPath$JarLoader.access0(URLClassPath.java:756)
    at sun.misc.URLClassPath$JarLoader.run(URLClassPath.java:838)
    at sun.misc.URLClassPath$JarLoader.run(URLClassPath.java:831)
    ... 20 more
java.util.zip.ZipException: error in opening zip file
    at java.util.zip.ZipFile.open(Native Method)
    at java.util.zip.ZipFile.<init>(ZipFile.java:219)
    at java.util.zip.ZipFile.<init>(ZipFile.java:149)
    at java.util.jar.JarFile.<init>(JarFile.java:166)
    at java.util.jar.JarFile.<init>(JarFile.java:103)
    at sun.misc.URLClassPath$JarLoader.getJarFile(URLClassPath.java:893)
    at sun.misc.URLClassPath$JarLoader.access0(URLClassPath.java:756)
    at sun.misc.URLClassPath$JarLoader.run(URLClassPath.java:838)
    at sun.misc.URLClassPath$JarLoader.run(URLClassPath.java:831)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.misc.URLClassPath$JarLoader.ensureOpen(URLClassPath.java:830)
    at sun.misc.URLClassPath$JarLoader.<init>(URLClassPath.java:803)
    at sun.misc.URLClassPath.run(URLClassPath.java:530)
    at sun.misc.URLClassPath.run(URLClassPath.java:520)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.misc.URLClassPath.getLoader(URLClassPath.java:519)
    at sun.misc.URLClassPath.getLoader(URLClassPath.java:492)
    at sun.misc.URLClassPath.getNextLoader(URLClassPath.java:457)
    at sun.misc.URLClassPath.getResource(URLClassPath.java:211)
    at java.net.URLClassLoader.run(URLClassLoader.java:365)
    at java.net.URLClassLoader.run(URLClassLoader.java:362)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:411)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:304)
    at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:401)
java.security.PrivilegedActionException: java.util.zip.ZipException: error in opening zip file
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.misc.URLClassPath.getLoader(URLClassPath.java:519)
    at sun.misc.URLClassPath.getLoader(URLClassPath.java:492)
    at sun.misc.URLClassPath.getNextLoader(URLClassPath.java:457)
    at sun.misc.URLClassPath.getResource(URLClassPath.java:211)
    at java.net.URLClassLoader.run(URLClassLoader.java:365)
    at java.net.URLClassLoader.run(URLClassLoader.java:362)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:411)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:304)
    at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:401)
Caused by: java.util.zip.ZipException: error in opening zip file
    at java.util.zip.ZipFile.open(Native Method)
    at java.util.zip.ZipFile.<init>(ZipFile.java:219)
    at java.util.zip.ZipFile.<init>(ZipFile.java:149)
    at java.util.jar.JarFile.<init>(JarFile.java:166)
    at java.util.jar.JarFile.<init>(JarFile.java:103)
    at sun.misc.URLClassPath$JarLoader.getJarFile(URLClassPath.java:893)
    at sun.misc.URLClassPath$JarLoader.access0(URLClassPath.java:756)
    at sun.misc.URLClassPath$JarLoader.run(URLClassPath.java:838)
    at sun.misc.URLClassPath$JarLoader.run(URLClassPath.java:831)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.misc.URLClassPath$JarLoader.ensureOpen(URLClassPath.java:830)
    at sun.misc.URLClassPath$JarLoader.<init>(URLClassPath.java:803)
    at sun.misc.URLClassPath.run(URLClassPath.java:530)
    at sun.misc.URLClassPath.run(URLClassPath.java:520)
    ... 15 more
java.util.zip.ZipException: error in opening zip file
    at java.util.zip.ZipFile.open(Native Method)
    at java.util.zip.ZipFile.<init>(ZipFile.java:219)
    at java.util.zip.ZipFile.<init>(ZipFile.java:149)
    at java.util.jar.JarFile.<init>(JarFile.java:166)
    at java.util.jar.JarFile.<init>(JarFile.java:103)
    at sun.misc.URLClassPath$JarLoader.getJarFile(URLClassPath.java:893)
    at sun.misc.URLClassPath$JarLoader.access0(URLClassPath.java:756)
    at sun.misc.URLClassPath$JarLoader.run(URLClassPath.java:838)
    at sun.misc.URLClassPath$JarLoader.run(URLClassPath.java:831)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.misc.URLClassPath$JarLoader.ensureOpen(URLClassPath.java:830)
    at sun.misc.URLClassPath$JarLoader.<init>(URLClassPath.java:803)
    at sun.misc.URLClassPath.run(URLClassPath.java:530)
    at sun.misc.URLClassPath.run(URLClassPath.java:520)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.misc.URLClassPath.getLoader(URLClassPath.java:519)
    at sun.misc.URLClassPath.getLoader(URLClassPath.java:492)
    at sun.misc.URLClassPath.getNextLoader(URLClassPath.java:457)
    at sun.misc.URLClassPath.getResource(URLClassPath.java:211)
    at java.net.URLClassLoader.run(URLClassLoader.java:365)
    at java.net.URLClassLoader.run(URLClassLoader.java:362)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:411)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:304)
    at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:401)
java.util.zip.ZipException: error in opening zip file
    at java.util.zip.ZipFile.open(Native Method)
    at java.util.zip.ZipFile.<init>(ZipFile.java:219)
    at java.util.zip.ZipFile.<init>(ZipFile.java:149)
    at java.util.jar.JarFile.<init>(JarFile.java:166)
    at java.util.jar.JarFile.<init>(JarFile.java:103)
    at sun.misc.URLClassPath$JarLoader.getJarFile(URLClassPath.java:893)
    at sun.misc.URLClassPath$JarLoader.access0(URLClassPath.java:756)
    at sun.misc.URLClassPath$JarLoader.run(URLClassPath.java:838)
    at sun.misc.URLClassPath$JarLoader.run(URLClassPath.java:831)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.misc.URLClassPath$JarLoader.ensureOpen(URLClassPath.java:830)
    at sun.misc.URLClassPath$JarLoader.<init>(URLClassPath.java:803)
    at sun.misc.URLClassPath.run(URLClassPath.java:530)
    at sun.misc.URLClassPath.run(URLClassPath.java:520)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.misc.URLClassPath.getLoader(URLClassPath.java:519)
    at sun.misc.URLClassPath.getLoader(URLClassPath.java:492)
    at sun.misc.URLClassPath.getNextLoader(URLClassPath.java:457)
    at sun.misc.URLClassPath.getResource(URLClassPath.java:211)
    at java.net.URLClassLoader.run(URLClassLoader.java:365)
    at java.net.URLClassLoader.run(URLClassLoader.java:362)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:411)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:304)
    at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:401)
java.security.PrivilegedActionException: java.util.zip.ZipException: error in opening zip file
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.misc.URLClassPath$JarLoader.ensureOpen(URLClassPath.java:830)
    at sun.misc.URLClassPath$JarLoader.<init>(URLClassPath.java:803)
    at sun.misc.URLClassPath.run(URLClassPath.java:530)
    at sun.misc.URLClassPath.run(URLClassPath.java:520)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.misc.URLClassPath.getLoader(URLClassPath.java:519)
    at sun.misc.URLClassPath.getLoader(URLClassPath.java:492)
    at sun.misc.URLClassPath.getNextLoader(URLClassPath.java:457)
    at sun.misc.URLClassPath.getResource(URLClassPath.java:211)
    at java.net.URLClassLoader.run(URLClassLoader.java:365)
    at java.net.URLClassLoader.run(URLClassLoader.java:362)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:411)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:304)
    at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:401)
Caused by: java.util.zip.ZipException: error in opening zip file
    at java.util.zip.ZipFile.open(Native Method)
    at java.util.zip.ZipFile.<init>(ZipFile.java:219)
    at java.util.zip.ZipFile.<init>(ZipFile.java:149)
    at java.util.jar.JarFile.<init>(JarFile.java:166)
    at java.util.jar.JarFile.<init>(JarFile.java:103)
    at sun.misc.URLClassPath$JarLoader.getJarFile(URLClassPath.java:893)
    at sun.misc.URLClassPath$JarLoader.access0(URLClassPath.java:756)
    at sun.misc.URLClassPath$JarLoader.run(URLClassPath.java:838)
    at sun.misc.URLClassPath$JarLoader.run(URLClassPath.java:831)
    ... 20 more

为什么会出现这个异常?如何解决?

来自Logcat:

java.security.PrivilegedActionException: java.util.zip.ZipException: error in opening zip file

来自文档:

This exception is thrown by doPrivileged(PrivilegedExceptionAction) and doPrivileged(PrivilegedExceptionAction, AccessControlContext context) to indicate that the action being performed threw a checked exception. The exception thrown by the action can be obtained by calling the getException method. In effect, an PrivilegedActionException is a "wrapper" for an exception thrown by a privileged action

检查文件是否未损坏,以及您是否可以访问文件所在的文件夹。

最后,我们使用 getException 获取更多详细信息