さて、私はこれについてのアイデアがすべてありません。発生しているすべての例外をキャッチ (およびテキスト ファイルに記録) するために、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;
}
}