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

我想检索一条错误消息,解释为什么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 ++进行编码,因此如果有人能够展示将错误捕获到字符串流中的方法,那将是理想的。

谢谢,兰迪

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

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

在您的进程中重定向stdout / stderr的最佳方法是使用freopen 。 这是一个StackOverflow问题,专门针对该主题。

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

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