Java JNI GetMethodID return NULL

13,274

If instantiating a inner class using JNI the parent must be passed also in the signature used with GetMethodIdin order to receive a valid jmethodID.

Assuming Bis a inner class of A and has a constructor like: public B(int someint) the following code would work(jobj is pointing to a instance of A):

jclass jclazz = env->FindClass("org/somepackage/A$B");
assert(jclazz != nullptr);
jmethodID mid = env->GetMethodID(jclazz, "<init>", "(Lorg/somepackage/A;I)V");
assert(mid != nullptr);
env->NewObject(jclazz, mid, jobj, 1);

A solution to the ops question is:

 jclass cls = env->FindClass("com/example/parkingcontrolsystem/CameraActivity$RecognitionResult");
 std::cout << "Class: " << cls << std::endl;
 jmethodID constructor = env->GetMethodID(cls, "<init>","Lcom/example/parkingcontrolsystem/CameraActivity;Ljava/lang/String;IIII)V");
 std::cout << "Method: " << constructor << std::endl;
 recognition_result = env->NewObject(cls, constructor, object, "Hello from JNI", 0, 0, 50, 100);
 std::cout << "Object: " << recognition_result << std::endl;

Note: Creds to Selven who posted also the same answer in the comments but didn`t post an answer.

Share:
13,274
herolover
Author by

herolover

Updated on June 04, 2022

Comments

  • herolover
    herolover almost 2 years

    I have this class in Java:

    public class CameraActivity extends Activity {
    
      ...      
    
      public class RecognitionResult {
        public String text;
        public int x;
        public int y;
        public int width;
        public int height;
    
        public RecognitionResult(String text, int x, int y, int width, int height) {
          this.text = text;
          this.x = x;
          this.y = y;
          this.width = width;
          this.height = height;
        }
      }
    }
    

    And this is my JNI code:

    extern "C"
    jobject Java_com_example_parkingcontrolsystem_CameraActivity_recognizeNumberPlate(JNIEnv *env,
                                                                                      jobject object,
                                                                                      jstring filename)
    {
      jclass cls = env->FindClass("com/example/parkingcontrolsystem/CameraActivity$RecognitionResult");
      std::cout << "Class: " << cls << std::endl;
    
      jmethodID constructor = env->GetMethodID(cls, "<init>", "(Ljava/lang/String;IIII)V");
      std::cout << "Method: " << constructor << std::endl;
    
      recognition_result = env->NewObject(cls, constructor, "Hello from JNI", 0, 0, 50, 100);
      std::cout << "Object: " << recognition_result << std::endl;
    
      return recognition_result;
    }
    

    FindClass returns not a NULL, OK. But GetMethodID always returns zero. I tried to make the default constructor without args, and than use the "()V" signature, but GetMethodID returns NULL.

    What is wrong?