当通过JNI加载JVM失败时,如何获得错误消息?

tyu7yeag  于 2022-11-07  发布在  其他
关注(0)|答案(3)|浏览(108)

我想检索一个错误消息,解释为什么JVM无法加载。从下面提供的示例中:
http://java.sun.com/docs/books/jni/html/invoke.html
我摘录了这个例子:

/* Create the Java VM */
 res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);

 if (res < 0) {
     // retrieve verbose error here?
     fprintf(stderr, "Can't create Java VM\n");
     exit(1);
 }

在我的特定情况下,我在vm_args中提供了无效参数,并希望看到我在命令行上得到的结果:“无法识别的选项:-foo=巴”
在进一步的测试中,看起来jvm正在把我想要的消息放到stdout或stderr中。我相信我需要捕获stdout和stderr来得到我想要的错误(当然,除非有更简单的方法)。我正在用C++编码,所以如果有人能展示一种方法来捕获错误到一个字符串流中,那将是理想的。
谢谢,兰迪

8ljdwjyq

8ljdwjyq1#

我能够通过使用下面描述的“vfprintf”选项获得所需的内容:
https://web.archive.org/web/20111229234347/http://java.sun.com/products/jdk/faq/jnifaq-old.html
虽然我使用的是jdk1.2选项。

static string jniErrors;

static jint JNICALL my_vfprintf(FILE *fp, const char *format, va_list args)
{
    char buf[1024];
    vsnprintf(buf, sizeof(buf), format, args);
    jniErrors += buf;
    return 0;
}

...

JavaVMOption options[1];
options[0].optionString = "vfprintf";
options[0].extraInfo = my_vfprintf;

JavaVMInitArgs vm_args;
memset(&vm_args, 0, sizeof(vm_args));
vm_args.nOptions = 1;
vm_args.options = options;
vm_args.version = JNI_VERSION_1_4;
vm_args.ignoreUnrecognized = JNI_FALSE;

JNIEnv env;
JavaVM jvm;

jint res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);

if (res != JNI_OK)
    setError(jniErrors);

jniErrors.clear();

同样有趣的是,我一辈子都不能用freopen或dup2的任何技巧正确地捕获stdout或stderr。我可以加载我自己的dll并正确地重定向,但不能正确地加载jvm。无论如何,这样做更好,因为我希望错误在内存中而不是在文件中。

jgwigjjp

jgwigjjp2#

当我写这段代码时,我也会通过stdout/stderr得到错误。
在进程中重定向stdout/stderr的最好方法是使用freopen
然而,一旦该调用被传递,您将得到一个JNIEnv,并且所有进一步的错误检查都可以并且应该通过调用JNIEnv::ExceptionOccurred()来完成,这将返回一个Throwable对象,然后您可以使用JNI代码询问该对象。

pb3skfrl

pb3skfrl3#

在获得stdout和stderr(无论如何都需要它们)之后,将-Xcheck:jni添加到jvm命令行,以从jvm获得额外的与jni相关的警告。

相关问题