All code below works as expected, except for the indicated line that crashes. I have spent days scratching my head over this code, checking and re-checking the documentation. I would be delighted if someone could point out the no doubt obvious thing I'm missing.
Main.java:
public class Main {
    public static void main(String[] args) {
        Test tst = new Test();
        System.out.println((String)tst.test());
    }
}
Test.java
public class Test {
    static { System.loadLibrary("test"); }
    public native Object test();
}
test.c
#include <jni.h>
JNIEXPORT jobject JNICALL Java_Test_test(JNIEnv *env, jobject thiz) {
    const char* out = "success";
    do {
        jclass cls_cls = (*env)->FindClass(env, "java/lang/Class");
        if ( !cls_cls ) { out = "FindClass"; break; }
        jmethodID mfn = (*env)->GetStaticMethodID(
            env, cls_cls, "forName", "(Ljava/lang/String;)Ljava/lang/Class;"
        );
        if ( !mfn ) { out = "GetStaticMethodID"; break; }
        // **** lines above succeed, line below segfaults ****
        jclass cls = (jclass) (*env)->CallStaticObjectMethod(
            env, cls_cls, mfn, "java.lang.String"
        );
        if ( (*env)->ExceptionCheck(env) ) { out = "CallStaticObjectMethod"; break; }
    } while ( 0 );
    (*env)->ExceptionClear(env);
    return (jobject) (*env)->NewStringUTF(env, out);
}
compile/exec
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
Expected outcome, expressed in pure Java:
Class<?> cls_cls = Class.class;
Method mfn = cls_cls.getDeclaredMethod("forName", String.class);
Class<?> cls = (Class) mfn.invoke(null, "java.lang.String");
 
Aucun commentaire:
Enregistrer un commentaire