How do I get an error message when failing to load a JVM via JNI?

a 夏天 提交于 2019-12-03 08:46:00

I was able to get what I needed by using the "vfprintf" option described here:

http://java.sun.com/products/jdk/faq/jnifaq-old.html

although I used the jdk1.2 options. This code snippet summarizes my solution:

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();

Also interesting was that I could not for the life of me capture stdout or stderr correctly with any of the freopen or dup2 tricks. I could load my own dll and redirect correctly but not the jvm. Anyway, it's better this way because I wanted the errors in memory rather than in a file.

Jared Oberhaus

When I wrote this code I would also get the error via stdout/stderr.

The best way to redirect stdout/stderr in your process is by using freopen. Here is a StackOverflow question specifically about that subject.

However, once that call is passed, you will then have a JNIEnv, and all further error checking can and should be done by calling JNIEnv::ExceptionOccurred(), which will may return a Throwable object that you can then interrogate with your JNI code.

After getting a hold of stdout and stderr, which you'll need anyway, add -Xcheck:jni to your jvm command line to get extra jni-related warnings from the jvm.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!