Search code examples
javaandroid-ndkjava-native-interface

Is there a way to check if jobject is a local or global reference?


I cannot find an answer if there is a way to test an arbitrary jobject in order to detect if it is a local or global reference. I do not see it in JNI documentation.

The reason for this question is to add some error checking and logic for my custom JNI utilities. In my code jobject reference can come from different places (including from other users/modules) so I am looking for a way to test it.

For example I want to have a utility to "promote" a local to global reference, but it also should work with global references (that is it shouldn't crash or anything if a global reference is passed). I could try exception check but I don't know i can avoid false positives.

What can happen if DeleteLocalRef is called on a global reference. Documentation says either global or local can be passed to NewGlobalRef but I assume there will be a problem with deleting a wrong one.

jobject toGlobalRef(jobject& locRef)
{
    JNIEnv* env = jniEnv();  //gets correct JNIEnv* here

    if (locRef == NULL)
        return NULL;

    jobject globalRef = env->NewGlobalRef(locRef);
    env->DeleteLocalRef(locRef);
    locRef = NULL; 
    return globalRef;        
}

Solution

  • Don't know how I missed but looks like there is a function added in JNI 1.6 to check reference type:

    jobjectRefType GetObjectRefType(JNIEnv* env, jobject obj);
    
    The function GetObjectRefType returns one of the following enumerated values defined as a jobjectRefType:
    
    JNIInvalidRefType = 0,
    JNILocalRefType = 1,
    JNIGlobalRefType = 2,
    JNIWeakGlobalRefType = 3
    

    http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/functions.html