Recently I was working on a project that made use of the Java Native Interface (JNI). JNI is usually used for calling native functions from Java code. For example, if you want to implement some platform specific functionality or some very fast piece of code, you can use JNI to interact with the Java Virtual Machine calling your function. In that particular project we made the opposite, i.e used JNI to call Java code from C environment.
In order to execute Java code we first have to create a Java Virtual Machine to run it. This is done using JNI_CreateJavaVM() function. It returns a pointer to the newly created Java VM and a pointer to the JNI environment through which we do all our Java related operations.
When the code was written and everything should supposedly work I encountered a problem on which I spent a lot of debugging time. Once the Java code was called it ran up to a certain point and then got stuck. I thought it was some problem within the Java code and went on debugging it but everything seemed to be OK. It has taken us a while to get to the point and here it goes:
The Java VM was created during the initialization of the C module. Later on the process fork()-ed and our Java piece of code was actually activated by the forked process. I assumed accessing the same virtual machine is OK as long as I didn’t use the same pointer that I got from JNI_CreateJavaVM in the parent process, but instead called JNI_GetCreatedJavaVMs to retrieve a pointer to the existing virtual machine. Indeed the call successfully returned me a pointer, but apparently this scenario of multiple processing sharing the same VM is not supported, and calling Java methods that way causes the program to hang. Once we created the Java VM in the context of the process that actually called the Java methods the problem was solved.
I hope you stumble upon this post shortly after you have encountered a similar problem or prior to that, and I managed to save you some time.