xtcr1st1
xtcr1st1

Reputation: 13

JNI - FATAL ERROR in native method: Bad global or local ref passed to JNI

I checked the related questions on this error, but couldn't find the answer. I have the following code. The error is related to calling jLog method and if I take it out the error is gone, so I don't understand what is the problems - just my first experience with JNI:

static jclass util_class;
static jmethodID log_from_jni;
...
    util_class = (*env)->FindClass(env, "package/Util");
    if ((*env)->ExceptionOccurred(env)) {
        printf("Error occured when loading Util class\n");
    }
    log_from_jni = (*env)->GetStaticMethodID(env, util_class,
            "logFromJNI", "(Ljava/lang/String;)V");

    if ((*env)->ExceptionOccurred(env)) {
        printf("Error occured when loading logFromJNI method\n");
    }
...

void jLog(JNIEnv *env, char* cstr) {
    if (util_class != NULL || log_from_jni != NULL) {
        jstring str = (*env)->NewStringUTF(env, cstr);
        (*env)->CallStaticVoidMethod(env, util_class, log_from_jni, str);
    } else {
        printf(cstr);
    }

}

JNIEXPORT void JNICALL Java_package_callLog(JNIEnv * env, jobject obj) {\
    jLog(env, "JNI: Log");//
}

Thank you.

Upvotes: 1

Views: 1277

Answers (1)

Jorn Vernee
Jorn Vernee

Reputation: 33905

A jclass is just another Java heap object, which means it can be moved by the garbage collector, which would make the utill_class that you saved basically a dangling pointer.

If you want a jclass that stays valid, you need to create a global reference for it:

util_class = (jclass) (*env)->NewGlobalRef(env, (*env)->FindClass(env, "package/Util"));

Upvotes: 4

Related Questions