Call static Java method from separate thread using JNI

Nathan F. :

I'm trying to use JNI in android to make a function pointer that a native library I'm using uses forward it's call to java.

When initializeStateController is called, a new thread is made using pthread_create that calls the function pointer whenever the state of the State Controller changes.

However, when I try to call GetStaticMethodID from state_exec in C, I'm getting the following error:

JNI DETECTED ERROR IN APPLICATION: jclass is an invalid local reference: 0xec500019 (0xdead4321) in call to GetStaticMethodID

This is my current code:

C Code

state_controller *controller;
JavaVM* gJvm = NULL;
static jclass sc_class;

JNIEnv* getEnv() {
    JNIEnv *env;
    int status = (*gJvm)->GetEnv(gJvm, (void**)&env, JNI_VERSION_1_6);
    if(status < 0) {
         status = (*gJvm)->AttachCurrentThread(gJvm, &env, NULL);
        if(status < 0) {
            return NULL;
        }
    }
    return env;
}

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* pjvm, void* reserved) {
    gJvm = pjvm;
    JNIEnv *env = getEnv();

    sc_class = (*env)->FindClass(env, "com/my/package/StateController");

    return JNI_VERSION_1_6;
}

int state_exec(int state, int from) {
    JNIEnv *env = getEnv();
    jmethodID mid = (*env)->GetStaticMethodID(env, sc_class, "stateExec","(II)I");
    jint result = (*env)->CallStaticIntMethod(env, sc_class, mid, state, from);

    return (int) result;
}

// This part is unimportant.
// This is just where I hand the function pointer
// to the library to use.

JNIEXPORT void JNICALL 
Java_com_my_package_StateController_initializeStateController
(
        JNIEnv *env,
        jobject jobj
) {
    controller = new_state_controller(
        state_exec
    );
    sc_start_controller(controller);
}

Java

package com.my.package;

class StateController {

    public native void initializeStateController();

    public static int stateExec(int state, int from) {
        Log.d("StateTest", "State " + state + " -> " + from);
        return 0;
    }
}

. . . 

(new StateController()).initializeStateController();
Dima Kozhevin :

It turns out that the FindClass method only returns local references, not global. In order to make this work you need to make it a global reference. You can do this as demonstrated below.

// Replace

    sc_class = (*env)->FindClass(env, "com/my/package/StateController");

// With

    sc_class = (*env)->NewGlobalRef(
        env, 
        (*env)->FindClass(
            env, 
            "com/my/package/StateController"
        )
    );

// Later when you are done with the class reference, run this to free it.

    (*env)->DeleteGlobalRef(env, sc_class);

From Android Docs:

Bug: Mistakenly assuming FindClass() returns global references

FindClass() returns local references. Many people assume otherwise. In a system without class unloading (like Android), you can treat jfieldID and jmethodID as if they were global. (They’re not actually references, but in a system with class unloading there are similar lifetime issues.) But jclass is a reference, and FindClass() returns local references. A common bug pattern is “static jclass”. Unless you’re manually turning your local references into global references, your code is broken.

https://android-developers.googleblog.com/2011/11/jni-local-reference-changes-in-ics.html

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Java

Call Kotlin object with class delegation from Java as a static method

From Java

How to call a method with a separate thread in Java?

From Java

How to call getClass() from a static method in Java?

From Java

Java: how to call non static method from main method?

From Java

Android ndk : Problem for call of Java method from c++ with jni

From Java

Call a static java method of another package from native code

From Java

How To Call JAVA Methods from inside of a Thread in JNI

From Dev

Unable to make JNI call from c++ to java in android lollipop using jni

From Dev

Calling a static void Java method from JNI

From Dev

C++ Multithread Java JNI method Call

From Dev

Call fortran dll from java using JNI

From Dev

Call Java Enum method from JNI

From Dev

Verify a method call happening in a separate thread/thread pool using Moq

From Dev

How to call a static JNI function from Kotlin?

From Dev

Java Thread lock on static method

From Dev

Java - How to access static synchronized method from another Thread?

From Dev

C++ Call an abstract method from a static method using *this

From Dev

Java Program terminates after JNI method call

From Dev

Call a JNI method from another JNI method

From Dev

Calling a Java Method from the native code using jni

From Dev

Calling java function from c++ using jni: Failed to find static method id

From Dev

How to call a function with arguments in C++ from JAVA using JNI?

From Dev

Cross Thread Static Method Call

From Dev

Java - Thread Safety of a static method

From Dev

C# How can I change textbox.Text from a static method in a separate class and thread

From Dev

How to call a method from static PreferenceFragment using onPreferenceClick

From Dev

Call static method from constructor in Java

From Dev

Freemarker call static java method from java.lang.Integer

From Dev

JNI Rust how to pass arguments to call_static_method?

Related Related

  1. 1

    Call Kotlin object with class delegation from Java as a static method

  2. 2

    How to call a method with a separate thread in Java?

  3. 3

    How to call getClass() from a static method in Java?

  4. 4

    Java: how to call non static method from main method?

  5. 5

    Android ndk : Problem for call of Java method from c++ with jni

  6. 6

    Call a static java method of another package from native code

  7. 7

    How To Call JAVA Methods from inside of a Thread in JNI

  8. 8

    Unable to make JNI call from c++ to java in android lollipop using jni

  9. 9

    Calling a static void Java method from JNI

  10. 10

    C++ Multithread Java JNI method Call

  11. 11

    Call fortran dll from java using JNI

  12. 12

    Call Java Enum method from JNI

  13. 13

    Verify a method call happening in a separate thread/thread pool using Moq

  14. 14

    How to call a static JNI function from Kotlin?

  15. 15

    Java Thread lock on static method

  16. 16

    Java - How to access static synchronized method from another Thread?

  17. 17

    C++ Call an abstract method from a static method using *this

  18. 18

    Java Program terminates after JNI method call

  19. 19

    Call a JNI method from another JNI method

  20. 20

    Calling a Java Method from the native code using jni

  21. 21

    Calling java function from c++ using jni: Failed to find static method id

  22. 22

    How to call a function with arguments in C++ from JAVA using JNI?

  23. 23

    Cross Thread Static Method Call

  24. 24

    Java - Thread Safety of a static method

  25. 25

    C# How can I change textbox.Text from a static method in a separate class and thread

  26. 26

    How to call a method from static PreferenceFragment using onPreferenceClick

  27. 27

    Call static method from constructor in Java

  28. 28

    Freemarker call static java method from java.lang.Integer

  29. 29

    JNI Rust how to pass arguments to call_static_method?

HotTag

Archive