I’m embedding a JVM into my webserver which has 4 worker threads that never die. The following code runs on each http request inside any one of 4 workers:
// normally I would do URL routing here first, but this is just a JNI test now
jclass cls;
jmethodID method;
jobjectArray args;
jclass stringClass;
jstring jstr;
(*jvm)->AttachCurrentThread (jvm, &env, NULL);
cls = (*env)->FindClass(env, "HelloWorldClass");
method = (*env)->GetStaticMethodID(env, cls, "main", "([Ljava/lang/String;)V");
jstr = (*env)->NewStringUTF(env, "Hello world!");
stringClass = (*env)->FindClass(env, "java/lang/String");
args = (*env)->NewObjectArray(env, 1, stringClass, jstr);
(*env)->CallStaticVoidMethod(env, cls, method, args);
When I step through with the debugger, it works. But when I put some load on it with weighttp benchmark, it randomly segfaults either on the FindClass() line or the CallSTaticVoidMethod() line. What could be the problem? I read through a lot of docs, I don’t see how I would need to lock or free anything here.
This is pretty much the most basic JNI code that is possible, carried over from the official doc: http://java.sun.com/docs/books/jni/html/invoke.html
Looks like I have put JNIEnv* into global scope. While that itself shouldn’t have caused a problem because it gets overwritten in each thread where it gets used, it appears as if JNI wants/needs to internally free it every time it’s used. The wonders of API design!