1

さて、私はこれについてのアイデアがすべてありません。発生しているすべての例外をキャッチ (およびテキスト ファイルに記録) するために、Java の例外パイプラインにフックする方法を知っている人はいますか?

状況は次のとおりです。JAR ファイル (A) にライブラリがあり、このライブラリは 2 番目の JAR ファイル (B) に依存しています。A は単なるクラス ライブラリであるため、メイン クラスはありません。JNI を介してアクセスし、呼び出しています。私が抱えている問題はこれです。A がロードされた状態で JNI を初期化しようとすると、JNI は特定できないエラーを返します。

このエラーは、B の静的コード (メソッドの外側) で発生している Log4J のロガー ユニットのインスタンス化が原因であると強く疑っています。これは、ログ ファイルのアクセス許可の問題の結果として IOException をスローしていると考えられます。ただし、リンク段階(AがBをインポートするとき)で例外(問題の原因であると思われる)がスローされ、try-catchでキャッチできないため、何が起こっているのかを見つけるのに問題がありますブロック。また、main メソッドがないため、この例外をキャッチするために try-catch ブロックを配置する明確な場所がありません。

いずれかの JAR で発生するすべての例外をキャッチし、それらをテキスト ファイルにダンプする何らかの方法が必要です。B を (簡単に) 変更することはできません (逆コンパイルされた JAR はありません)。何か案は?

指定されたライブラリとオプションで JNI を呼び出す C コードを次に示します。

_DLL_EXPORT PyObject *initVM(PyObject *self, PyObject *args, PyObject *kwds)
{
    static char *kwnames[] = {
        "classpath", "initialheap", "maxheap", "maxstack",
        "vmargs", NULL
    };
    char *classpath = NULL;
    char *initialheap = NULL, *maxheap = NULL, *maxstack = NULL;
    char *vmargs = NULL;

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzzzz", kwnames,
                                     &classpath,
                                     &initialheap, &maxheap, &maxstack,
                                     &vmargs))
        return NULL;

    if (env->vm)
    {
        PyObject *module_cp = NULL;

        if (initialheap || maxheap || maxstack || vmargs)
        {
            PyErr_SetString(PyExc_ValueError,
                            "JVM is already running, options are ineffective");
            return NULL;
        }

        if (classpath == NULL && self != NULL)
        {
            module_cp = PyObject_GetAttrString(self, "CLASSPATH");
            if (module_cp != NULL)
                classpath = PyString_AsString(module_cp);
        }

        if (classpath && classpath[0])
            env->setClassPath(classpath);

        Py_XDECREF(module_cp);

        return getVMEnv(self);
    }
    else
    {
        JavaVMInitArgs vm_args;
        JavaVMOption vm_options[32];
        JNIEnv *vm_env;
        JavaVM *vm;
        unsigned int nOptions = 0;
        PyObject *module_cp = NULL;

        vm_args.version = JNI_VERSION_1_4;
        JNI_GetDefaultJavaVMInitArgs(&vm_args);

        if (classpath == NULL && self != NULL)
        {
            module_cp = PyObject_GetAttrString(self, "CLASSPATH");
            if (module_cp != NULL)
                classpath = PyString_AsString(module_cp);
        }

#ifdef _jcc_lib
        PyObject *jcc = PyImport_ImportModule("jcc");
        PyObject *cp = PyObject_GetAttrString(jcc, "CLASSPATH");

        if (classpath)
            add_paths("-Djava.class.path=", PyString_AsString(cp), classpath,
                      &vm_options[nOptions++]);
        else
            add_option("-Djava.class.path=", PyString_AsString(cp),
                       &vm_options[nOptions++]);

        Py_DECREF(cp);
        Py_DECREF(jcc);
#else
        if (classpath)
            add_option("-Djava.class.path=", classpath,
                       &vm_options[nOptions++]);
#endif

        Py_XDECREF(module_cp);

        if (initialheap)
            add_option("-Xms", initialheap, &vm_options[nOptions++]);
        if (maxheap)
            add_option("-Xmx", maxheap, &vm_options[nOptions++]);
        if (maxstack)
            add_option("-Xss", maxstack, &vm_options[nOptions++]);

        if (vmargs)
        {
#ifdef _MSC_VER
            char *buf = _strdup(vmargs);
#else
            char *buf = strdup(vmargs);
#endif
            char *sep = ",";
            char *option;

            for (option = strtok(buf, sep); option; option = strtok(NULL, sep))
            {
                if (nOptions < sizeof(vm_options) / sizeof(JavaVMOption))
                    add_option("", option, &vm_options[nOptions++]);
                else
                {
                    free(buf);
                    for (unsigned int i = 0; i < nOptions; i++)
                        delete vm_options[i].optionString;
                    PyErr_Format(PyExc_ValueError, "Too many options (> %d)",
                                 nOptions);
                    return NULL;
                }
            }
            free(buf);
        }

        //vm_options[nOptions++].optionString = "-verbose:gc";
        //vm_options[nOptions++].optionString = "-Xcheck:jni";

        vm_args.nOptions = nOptions;
        vm_args.ignoreUnrecognized = JNI_FALSE;
        vm_args.options = vm_options;
 if (JNI_CreateJavaVM(&vm, (void **) &vm_env, &vm_args) < 0)
        {
            for (unsigned int i = 0; i < nOptions; i++)
                delete vm_options[i].optionString;

            PyErr_Format(PyExc_ValueError,
                         "An error occurred while creating Java VM");
            return NULL;
        }

        env->set_vm(vm, vm_env);

        for (unsigned int i = 0; i < nOptions; i++)
            delete vm_options[i].optionString;

        t_jccenv *jccenv = (t_jccenv *) PY_TYPE(JCCEnv).tp_alloc(&PY_TYPE(JCCEnv), 0);
        jccenv->env = env;

#ifdef _jcc_lib
        registerNatives(vm_env);
#endif

        return (PyObject *) jccenv;
    }
}
4

1 に答える 1