hanswe
hanswe

Reputation: 113

JNI stale local reference error accessing the caller object

I can't get rid of this error message

JNI ERROR (app bug): accessed stale local reference 0x... (index ...)

I'm trying to access from native the isInterrupted() method of the JNI caller class, which is a Java thread. The thread loop is entirely native, spawns other pthreads and holds mutexes. I need a way for the main Android activity to inform the thread that it should stop e.g. by Java's interrupt() at the first safe moment.

The scenario is quite simple and clean, nothing else happens between the lines:

public class MyThread extends Thread {
  public native static int native_world_entry();
  public void run() {
    native_world_entry();
  }
  static {
   System.loadLibrary("mylib");
  }
}

The native code being the following:

jint Java_..._1entry(JNIEnv* env, jobject thiz) {
  //jobject jj = (*env)->NewGlobalRef(env, thiz);
  jclass sclass = (*env)->FindClass(env, "java/lang/Thread");
  jmethodID inted = (*env)->GetMethodID(env, sclass, "isInterrupted", "()Z");
  LOGI("Checking");
  jboolean status = (*env)->CallBooleanMethod(env, thiz, inted);
  ...
}

All good untill CallBooleanMethod() as previous calls are successful and "Checking" is displayed. I've tried to add the commented line and change CallBooleanMethod()'s argument accordingly but the error is the same.

Besides the error I don't catch the reason why a global reference is needed in this case.. Any help is appreciated.

Upvotes: 1

Views: 3024

Answers (1)

Leonidos
Leonidos

Reputation: 10518

I think it is because native_world_entry is static. So thiz is not MyThread istance. It is MyThread class instance. Add extra param to native_world_entry method to pass thread handler explicitly, e.g. native_world_entry(this).

P.S. Also you can use Thread.currentThread() to get current thread.

Upvotes: 1

Related Questions