Search code examples
javac++enumsjava-native-interfacewrapper

Object creation in JNI


I have a class and an enum inside it like so:

public class ppmerrJNI 
{
   public enum ppm_err_e {
        ONE(0),
        TWO(1),
        THREE(2);

         private int code;

         private ppm_err_e(int code) {
           this.code = code;
         }

         public int getValue() {
           return code;
         }

        ppm_err_e getObj(int i) {
            return ppm_err_e.values()[i];
        }
    };
...
}

and I have JNI wrapper function declared like so:

JNIEXPORT jobject JNICALL Java_ppmerrJNI_ppm_1get_1last_1error(JNIEnv *env, jobject thisObj) {
       int someNumber = 5;

       jclass employeeClass = (*env)->FindClass(env,"ppmerrJNI$ppm_err_e");
       jmethodID midConstructor = (*env)->GetMethodID(env, employeeClass, "<init>", "(I)V");
       jobject employeeObject = (*env)->NewObject(env, employeeClass, midConstructor, someNumber);
       return employeeObject ;
}

On the second line (GetMethodId) I get: "Exception in thread "main" java.lang.NoSuchMethodError: ".

Basically, I want to call constructor of enum type "ppm_err_e", which resides inside of a class "ppmerrJNI". I want to return an enum object based on someNumber number and this is the approach I've taken; can settle for any other possible solution too.

I've also tried with:

jmethodID constructor = (*env)->GetMethodID(env, enumClass, "getObj", "(I)LppmerrJNI$ppm_err_e;");

but it always returned null.

Thank you in advance!


Solution

  • You can't instantiate enums. That was the reason why I couldn't call JNI's NewObject() method (enum permits only private constructors, so instantiation is not possible - you need public constructor). I solved it by making a method inside the outer class which takes enums index as an argument and returns corresponding enum instance. The method is called in JNI via CallObjectMethod() instead of NewObject().