Search code examples
javacconstructorjava-native-interfacewrapper

JNI GetMethodID not working for constructor of inner class


I have a class with a private subclass. I want to create an instance of that subclasss in a JNI wrapper and return it. I've googled and tried to make it work but with no success (methodID is null). Any suggestions?

JNIEXPORT jobject JNICALL Java_some_Class_some_Jni_Method(JNIEnv *env, jobject this) {
        jclass cls = (*env)->FindClass(env, "someClass$someSubclass");
        if (cls == NULL)
            printf("jclass error.");

        jmethodID methodID = (*env)->GetMethodID(env, cls, "<init>", "()V"); // -> problem!
        if (methodID == NULL)
            printf("jmethodID error.");

        jobject obj = (*env)->NewObject(env, cls, methodID);
        if (obj == NULL)
            printf("jobject error.");

        return obj;
}

EDIT1: adding class definition:

public class someClass 
{ 
    private class someSubclass {    

        public someSubclass() {
        }
    ...
    }
...
}

EDIT2: Ok I figured out you need parent class in the GetMethodID signature, so in my example: jmethodID methodID = (*env)->GetMethodID(env, cls, "<init>", "(LsomeClass;)V");

But now I get EXCEPTION_ACCESS_VIOLATION with NewObject function.

EDIT3: I also needed to add calling class object/pointer to the NewObject function: jobject obj = (*env)->NewObject(env, cls, methodID, this);

Constructor of nested class is now called properly.


Solution

  • You need parent class in the GetMethodID signature, so in my example: jmethodID methodID = (*env)->GetMethodID(env, cls, "<init>", "(LsomeClass;)V");

    And I also needed to add calling class object/pointer to the NewObject function: jobject obj = (*env)->NewObject(env, cls, methodID, this);