Jabeer Ahmed
Jabeer Ahmed

Reputation: 33

JNI GetMethodID for 3rd party library returns NULL

I am trying to get a constructor to a 3rd party library class such as "android.util.Size". But for some reason I get NULL returned when ever I try to query a field or method id from android core library. Any Idea why?

#include <stdio.h>
#include <android/log.h>
#include <jni.h>

#define LOG(LOG_TAG,...)  ((void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))
#define LOGE(LOG_TAG,...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
#define TAG "TEST"

#define CLS_SIZE "android/util/Size"
int register_SizeStruct(JNIEnv* env){
    LOG(TAG, "Registering Size");
    jclass clazz   = (jclass) env->NewGlobalRef(env->FindClass(CLS_SIZE));
    jmethodID init = env->GetMethodID(clazz, "<init>", " (II)V");

    if (clazz == NULL) LOGE(TAG, "Couldn't Register class " CLS_SIZE);
    if (init  == NULL) LOGE(TAG, "Couldn't Register Contructor for " CLS_SIZE);

    if((clazz  == NULL) || (init   == NULL)) {
        LOGE(TAG, "ERROR-Couldn't register Size struct");
        return -1;
    }
    return 0;
}

jint JNI_OnLoad(JavaVM* aVm, void* aReserved)
{
    JNIEnv* env;
    if (aVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK){
        LOGE (TAG, "Failed to get JNI_1_6 environment");
        return -1;
    }
    register_SizeStruct(env);
    return JNI_VERSION_1_6;
}

Here's the log

I/TEST( 2532): Registering Size
E/TEST( 2532): Couldn't Register Contructor for android/util/Size
E/TEST( 2532): ERROR-Couldn't register Size struct
D/AndroidRuntime( 2532): Shutting down VM
E/AndroidRuntime( 2532): FATAL EXCEPTION: main
E/AndroidRuntime( 2532): Process: com.example.testapp, PID: 2532
E/AndroidRuntime( 2532): java.lang.NoSuchMethodError: no non-static method "Landroid/util/Size;.<init> (II)V"
E/AndroidRuntime( 2532):    at java.lang.Runtime.nativeLoad(Native Method)
E/AndroidRuntime( 2532):    at java.lang.Runtime.doLoad(Runtime.java:428)
E/AndroidRuntime( 2532):    at java.lang.Runtime.loadLibrary(Runtime.java:369)
E/AndroidRuntime( 2532):    at java.lang.System.loadLibrary(System.java:989)
E/AndroidRuntime( 2532):    at com.example.testapp.MainActivity.<clinit>(MainActivity.java:38)
E/AndroidRuntime( 2532):    at java.lang.reflect.Constructor.newInstance(Native Method)
E/AndroidRuntime( 2532):    at java.lang.Class.newInstance(Class.java:1572)
E/AndroidRuntime( 2532):    at android.app.Instrumentation.newActivity(Instrumentation.java:1065)
E/AndroidRuntime( 2532):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2199)
E/AndroidRuntime( 2532):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
E/AndroidRuntime( 2532):    at android.app.ActivityThread.access$800(ActivityThread.java:144)
E/AndroidRuntime( 2532):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
E/AndroidRuntime( 2532):    at android.os.Handler.dispatchMessage(Handler.java:102)
E/AndroidRuntime( 2532):    at android.os.Looper.loop(Looper.java:135)
E/AndroidRuntime( 2532):    at android.app.ActivityThread.main(ActivityThread.java:5221)
E/AndroidRuntime( 2532):    at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime( 2532):    at java.lang.reflect.Method.invoke(Method.java:372)
E/AndroidRuntime( 2532):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)

Upvotes: 0

Views: 836

Answers (1)

Michael
Michael

Reputation: 58427

You've got a space in your signature string that shouldn't be there:

jmethodID init = env->GetMethodID(clazz, "<init>", " (II)V");   
                                                    ^-- RIGHT THERE

Remove that space. And also make sure that you're running this on an Android version corresponding to API level 21 or above, since that's where android.util.Size was added.

Upvotes: 1

Related Questions