I spent the weekend hacking at a Java JNI problem that I ended up believing might be impossible. JNI can be a very quirky process and straying off the path of a working example is certainly not for the faint of heart.

Using JNI for calling C methods from Java is not an overly difficult task and is by far the simplest way to invoke a C method from Java. Going the other direction however is where many minefields start to crop up. Getting C callback methods to talk to Java can be an exercise in frustration. I'm not really sure anyone has gotten this to work using straight JNI. The calls from C to Java work just fine if you do it from the same thread that Java called C from (that is, from the C method that Java called). The callback method, however, is in a new thread and attempting to communicate with Java from that new thread seems to not work using any of the methods proposed in the JNI specs such as creating a new JVM (which actually only gets you a handle to the exiting one) or using AttachCurrentThread after caching the JavaVM handle. Nothing worked for me in the callback thread when another JVM was pre-existing but unreachable, and I tried darned hard to make it work.

I was hitting this so hard because I was unwilling to settle for a solution that involved polling the C code, I wanted an event to trigger in Java - not for Java to spend all it's time asking C if anything had happened. Finally I had to abandon JNI for the actual callback (still using it to call from Java to C to setup the callback). What I am going to go with instead is a socket solution. I will send a UDP socket message from C to Java in response to C callback events. The socket code can be lightweight and reliable and gives me an event driven mechanism.

By the way, if you need to compile C JNI code from Cygwin gcc, be sure to take a look at http://www.inonit.com/cygwin/jni/invocationApi/archive.html

Back to Dave's Planet!