samedi 21 août 2021

JNI C getMethodID throws NoSuchMethodError for "getDeclaredMethod"

I've spent two days looking at and re-looking at this code, and simply can't see the error.

The code attempts to get a jmethodID for the getDeclaredMethod call linked to objB, in order to (later) get methodIDs of objB's instance methods (which are omitted for clarity).

(I also clutter the code by calling objB.getClass() in case this is the real source of reflection methods)

Instead, the 2nd and 3rd GetMethodIDs fail, for reasons I can't understand.

I would be most greatful to anyone who can point out the probably very obvious mistake.

public class Main {
    public static void main(String[] args) {
        ClsB objB = new ClsB();
        System.out.println((String)objB.test());
    }
}
public class ClsB {
    static { System.loadLibrary("test"); }
    public native Object test();
}
#include <jni.h>
JNIEXPORT jobject JNICALL Java_ClsB_test(JNIEnv *env, jobject objB) {
    const char* out = "success";
    do { // error checks commented out here for visual clarity
        jclass clsB = (*env)->GetObjectClass(env, objB);
        // if ( !clsB ) { out = "clsB"; break; }
        /* Class<?> Class_objB = objB.getClass() */
        jmethodID mgtc = (*env)->GetMethodID(env, clsB, "getClass", "()Ljava/lang/Class;");
        // if ( !mgtc ) { out = "mgtc"; break; }
        jobject Class_objB = (*env)->CallObjectMethod(env, objB, mgtc);
        // if ( (*env)->ExceptionCheck(env) ) { out = "Class_objB"; break; }
        const char* mgdm_nam = "getDeclaredMethod";
        const char* mgdm_sig = "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;";
        jmethodID mgdm;
        // **** ERROR **** either GetMethodID line below throws NoSuchMethodError
        mgdm = (*env)->GetMethodID(env, clsB, mgdm_nam, mgdm_sig);
//      mgdm = (*env)->GetMethodID(env, Class_objB, mgdm_nam, mgdm_sig);
        if ( !mgdm ) { out = "mgdm"; break; }
    } while ( 0 );
    (*env)->ExceptionClear(env);
    return (jobject) (*env)->NewStringUTF(env, out);
}
gcc -D_REENTRANT -fPIC -Wall -c test.c -o test.o -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux
gcc -D_REENTRANT -fPIC -Wall -shared -o libtest.so -O test.o
javac -Xlint:all Main.java
java -Xcheck:jni -Djava.library.path=. Main

Hoped-for outcome: "success", actual outcome "mgdm".





Aucun commentaire:

Enregistrer un commentaire