I would like to retrieve an error message that explains why the jvm failed to load. From the examples provided here:
http://java.sun.com/docs/books/jni/html/invoke.html
I extracted this example:
/* 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);
}
In my specific case I'm providing invalid arguments in the vm_args and would expect to see what I get on the command line: "Unrecognized option: -foo=bar"
On further testing it looks like the jvm is putting the message I want to stdout or stderr. I believe I would need to capture stdout and stderr to get the error I'm looking for (unless of course there is a simpler way). I'm coding in C++ so if someone can show a way to capture the error into a stringstream that would be ideal.
Thanks, Randy
-
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 callingJNIEnv::ExceptionOccurred(), which will may return aThrowableobject 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.
-
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.
0 comments:
Post a Comment