Search code examples
phpcjvmjava-native-interface

Building PHP Extension using JVM, need implementation ideas


I am in the process developing a PHP5 extension that that calls a Java class using JNI. The Extension and the core functions doing this are ready so far and work like expected in a single threaded (per process) environment. So using the extensions class functions in php script on command-line (php-cli) works without any problem. Now using that PHP extension as a apache module I experience problems in creating the JVM through JNI. The first call using the module works fine, the second call (while first call running and also after the first call has finished) the JVM is not created and returns a code less 0 (JNI_ERR). As I found out, it is a restriction that I only can have one JVM at a time per process. I test and run my module running apache with just one worker (using the -X switch).

My design of the module in the current stage is like this:

  • The extension constructor creates the JVM and makes some initialization.
  • Then I have a few methods to call and work with the java class (like passing parameters, etc) and to execute some methods of the java class.
  • My extension destructor frees all resources used and destroys the JVM formerly created in the constructor.

Well, first I thougth, that all would work out, but it does not. Not in the way like it is implemented for now. So I am a little stuck on ideas how to get this problem solved.

My questions are: Where should I create the JVM and how can I call it (the JNI Env) properly in a threaded environment (PHP as a Apache Module). I think I have to create the JVM somewhere using JNI_CreateJavaVM at module initialization and then use AttachCurrentThread / DetachCurrentThread ?! What happens, if another thread tries to attach to to the JVM thread, but there is already another Thread attached to it? Do I have to make some locking mechanism here? Or create the JVM in a extension class method, call inside that method all Java related methods and destroy the JVM at the end of the same extension class method? I do not like this idea at all. Even though I think it does not solve the problem of multiple JVM per process.

I hope things do not get too complicated.

So, basically, my problem is where to implement JVM creation/destruction calls and how to access the JNI Environment to call the Java class methods. Last but not least, is that anyways possible what I am trying to accomplish?

Some development details: My platform is Linux/Ubuntu Lucid 10.04 LTS, using Apache2 and PHP 5.2.16 (compiled from source). The module and core functions are developed in C, the Java JRE is 6.0.22 (Oracle download).


Solution

  • I would create the JVM instance on module load time (_init(void) function or something apache calls itself) and destroy it on _fini.

    If I remember correctly, you can attach multiple threads via AttachCurrentThread to the JVM. But you need to make sure that the pointer that is returned is only used in that thread. I would advise to use thread local storage for it. You can initialize the pointer with 0 on thread creation and do the attach in the first call to the function by the new thread.