As part of AIOJ, I need a way to invoke Java methods from inside of a signal handler. When I issue a POSIX AIO function from a native method, I tell it to raise a particular signal when the operation completes. The signal I am using is SIGRTMIN + 5. This signal works and at the moment and I’m hoping that no conflicts arise with any signal the JVM itself may be catching. I am able to register my signal handler using the sigaction system call and it works fine. The problem is, how do I invoke a Java method from my signal handler?
It’s actually quite easy. As part of my native code, I have the following:
static JavaVM *jvm;
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
// Initialize static jvm pointer.
jvm = vm;
}
The JNI_OnLoad(JavaVM *, void *) method gets called when the .so is loaded by the JVM. This provides a convenient way to get a pointer to the Java Virtual Machine. We store the pointer for later use in the jvm variable.
Our signal handler can now use the JVM reference to get a JNI Environment handle so we can invoke methods within Java. A possible signal handler could look like this:
void signalHandler(int signo, siginfo_t *info, void *context) {
JNIEnv *env;
jvm->GetEnv((void**)&env, JNI_VERSION);
env->CallVoidMethod(myObjRef, myMethodID);
}
If an exception is thrown in the signal handler, the exception gets caught by the thread that initiated the signal. The stack trace from the exception may be confusing because there’s no indication that it came from the signal handler.
To check out a real world example, check out the AIOJ source code in its subversion repository at the Apache Software Foundation.
RSS feed for comments on this post · TrackBack URI
Leave a reply