In JNI, is there a cleanup function for the JNIEnv pointer returned from AttachCurrentThread()?

c++, java-native-interface

Solution

The cleanup function is `DetachCurrentThread()`. You need to structure your code so that you know whether you're in an existing Java thread, in which case you already have the `JNIEnv*` passed into your JNI method, or you're in a native thread of your own devising, in which case you have to call `AttachCurrentThread()` before any other JNI call, and `DetachCurrentThread()` afterwards. Don't try to hide from this requirement.

Problem

I would like to know about the lifespan of the `JNIEnv *` obtained from the JNI function `AttachCurrentThread()`. Consider the following function that retrieves a `JNIEnv` pointer. ``` JNIEnv * RetrieveJniEnvPtr() { JavaVM * pJavaVM; // Assume pJavaVM is already initialized JNIEnv * pEnv = NULL; if(pJavaVM->GetEnv((void**)&pEnv, JNI_VERSION_1_6) != JNI_OK) { pJavaVM->AttachCurrentThread((void**) &pEnv, NULL); } return pEnv; } ``` Is there a cleanup call associated with the call to `AttachCurrentThread()`? Also, is this a lightweight function? Is it standard programming practice to call (in this example) `RetrieveJniEnvPtr()` many times within the same thread - or should the code only retrieve the `JNIEnv *` once for the lifetime of the thread?

Original source