views:

166

answers:

3

I am coding up something using the JNI Invocation API. A C program starts up a JVM and makes calls into it. The JNIenv pointer is global to the C file. I have numerous C functions which need to perform the same operation on a given class of jobject. So I wrote helper functions which take a jobject and process it, returning the needed data (a C data type...for example, an int status value). Is it safe to write C helper functions and pass jobjects to them as arguments?

i.e. (a simple example - designed to illustrate the question):

int getStatusValue(jobject jStatus)
{
  return (*jenv)->CallIntMethod(jenv,jStatus,statusMethod);
}

int function1()
{
  int status;
  jobject aObj = (*jenv)->NewObject
    (jenv,
     aDefinedClass,
     aDefinedCtor);

  jobject j = (*jenv)->CallObjectMethod
    (jenv,
     aObj,
     aDefinedObjGetMethod)

  status = getStatusValue(j);

  (*jenv)->DeleteLocalRef(jenv,aObj);
  (*jenv)->DeleteLocalRef(jenv,j);

  return status;

} 

Thanks.

A: 

I'm not acquainted with the details of JNI, but once thing I noticed is this:

return (*jenv)->CallIntMethod(jenv,jStatus,statusMethod);

That looks like the official JNI code and it is taking a jobect as a parameter. If it works for JNI, there is no reason it can't work for your code.

R Samuel Klatchko
A: 

All jni objects are valid until the native method returns. As long as you dont store non global jni objects between two jni calls everything should work.
The invocation of a jni function should work like this:

  1. Java function call
  2. create native local references
  3. call native function
  4. do your stuff
  5. exit native function
  6. release existing local references
  7. return to java

The step 4 can contain any code, local references stay valid until step 6 if not release before.
If you want to store jni objects on the c side between two calls to a native java function you have to create global references and release them later. Not releasing a global reference leads to memory leaks as the garbage collector is unable to free the related java objects.

josefx
I'm using the JNI Invocation API from C. The logic flow is like this:0. Start up JVM in C.1. Make a call from C into Java2. Handle results returned from Java.3. Release local references.4. Shutdown JVM.Steps 1-3 may happen N number of times between startup and shutdown of the JVM. I've done some testing and it seems to be OK. The documentation made me worried about passing these local references around...
bubbadoughball
A: 

I am trying to get this sorted too... (a month or so later than you...)

You say you are using the Invocation API, I am too, so don't think the reply above is related as it talks about call out from java, where as I (we) are calling into java.

I read [here][1] that when using the Invocation API, the references stay valid until the thread detaches from the JVM...

If you are using one thread only, then the references should be OK (as far as I can tell).

Multi threading will mean things change, and you can't store your JNIenv pointer either (I believe).

Unfortunately I am using multi threading... so am still figuring thing out in this regard...

Colin