JNI : Getting a JNI Interface Pointer from a Brand New Thread
807603Dec 13 2007 — edited Dec 19 2007I have a mutli-threaded native cross-platform SDK. I have built a class library and JNI integration into it that calls in on its own threads. I need to do some cleanup work (cleanup Global References) on some internal threads. I noticed that the JNI docs explicitly state that "JNI interface pointer(s) are only valid in the current thread. A native method, therefore, must never pass the interface pointer from one thread to another."
It is unclear whether this restriction applies to EVERY interface. Generally all functions in the JNI require either a JNIEnv* or a JNIVM*. There is a method GetJavaVM() that allows you to get a JNIVM* from a JNIEnv*. There is a method AttachCurrentThread() to obtain a JNIEnv* from a JNIVM*.
I was hoping to use GetJavaVM() to obtain a JavaVM* in one of the application calls from java, store this in a static variable, and then call AttachCurrentThread() on my internal thread to get a thread local JNIEnv* and do my cleanup. This obviously assumes that JavaVM* is not thread local; which is the only assumption I can make that makes any sense when viewing the methods available to a JNI developer.
However, when I read the GetJavaVM() function documentation @ http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/functions.html#wp23168
It reads:
"Returns the Java VM interface (used in the Invocation API) associated with the current thread."
Which sounds like JNIVM* is thread local also. If both JNIEnv* and JNIVM* are thread local, how is one ever able to call AttachCurrentThread()? More to the point, can I assume that JNIVM* IS NOT thread local; otherwise, how does one link to the Java virtual machine from a brand new thread
James A. Renton
Beverly, MA