如何通过JNI加载JVM失败时如何收到错误消息?

时间:2009-04-28 16:50:09

标签: java c++ jvm java-native-interface jvm-arguments

我想检索一条错误消息,解释为什么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 = bar”

在进一步测试时,看起来jvm正在将我想要的消息放入stdout或stderr。我相信我需要捕获stdout和stderr才能得到我正在寻找的错误(除非当然有更简单的方法)。我正在使用C ++进行编码,因此如果有人能够将错误捕获到字符串流中,那将是理想的。

谢谢, 好色

3 个答案:

答案 0 :(得分:4)

通过使用此处描述的“vfprintf”选项,我能够获得所需的内容:

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。无论如何,这种方式更好,因为我想要内存中的错误而不是文件中的错误。

答案 1 :(得分:0)

当我编写这段代码时,我也会通过stdout / stderr得到错误。

在您的流程中重定向stdout / stderr的最佳方法是使用freopen。以下是关于该主题的StackOverflow question

但是,一旦通过该通话,您就会有一个JNIEnv,所有进一步的错误检查都可以而且应该通过调用JNIEnv::ExceptionOccurred()来完成,这可能会返回Throwable然后,您可以使用JNI代码查询该对象。

答案 2 :(得分:0)

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