Android ndk : Problem for call of Java method from c++ with jni

20,559

Solution 1

After one day lost due to this bug, i finally found the solution of my problem :

The function javaCallJNI() is declared as a static native in Java, but, a static method can't call a non static method...

For resolve this problem, just replace :

public static native void javaCallJNI();

by

public native void javaCallJNI();

in JNITestActivity.java

Thank for your help and see soon ;)

Solution 2

What you have looks okay to me... but you might try replacing

jclass clazz = env->FindClass("com/test/jnitest/JNITestActivity");

With

jclass clazz = env->GetObjectClass(obj);
Share:
20,559

Related videos on Youtube

Crisic
Author by

Crisic

Updated on July 09, 2022

Comments

  • Crisic
    Crisic almost 2 years

    I try to work on Android NDK, my first test are not very conclusive, I need for help because I don't see where is my error.

    The following code compiles without problem but when is running on the emulator, the program returns SIGSEGV signal and no error is explicitly written in the logcat. however, a warning indicating that the Java class is not found appears. After a day of research on this problem, everything looks correct.

    Here is my Java code: JNITestActivity.java

    package com.test.jnitest;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.util.Log;
    
    public class JNITestActivity extends Activity {
    
        private static String LIB_NAME = "JNItest";
    
        static {
            System.loadLibrary(LIB_NAME);
        }
    
        public static native void javaCallJNI();
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
    
            Log.i("onCreate", "Native function begining");
            javaCallJNI();
            Log.i("onCreate", "Native function ending");
        }
    
        void callFromCPP() {
            Log.i("callFromCPP", "JNI can call JAVA !");
            return ;
        }
    
    }
    

    Here is my C++ code: testjni.cpp

    #include <jni.h>
    #include <android/log.h>
    
    #define  LOG_TAG    "testjni"
    #define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
    
    extern "C" {
        JNIEXPORT void JNICALL Java_com_test_jnitest_JNITestActivity_javaCallJNI(JNIEnv* env, jobject obj);
    };
    
    jint JNI_OnLoad(JavaVM* vm, void* reserved)
    {
        JNIEnv* env;
        if (vm->GetEnv((void**) &env, JNI_VERSION_1_6) != JNI_OK)
            return -1;
    
        LOGI("JNI INIT");
    
        return JNI_VERSION_1_6;
    }
    
    JNIEXPORT void JNICALL Java_com_test_jnitest_JNITestActivity_javaCallJNI(JNIEnv* env, jobject obj)
    {
        LOGI("JNI work !");
    
        jclass clazz = env->FindClass("com/test/jnitest/JNITestActivity");
        if (clazz == 0) {
            LOGI("FindClass error");
            return;
        }
        jmethodID javamethod = env->GetMethodID(clazz, "callFromCPP", "()V");
        if (javamethod == 0) {
            LOGI("GetMethodID error");
            return;
        }
        env->CallVoidMethod(obj, javamethod);
    }
    

    And here is my Makefile: Android.mk

    LOCAL_PATH:= $(call my-dir)
    include $(CLEAR_VARS)
    
    LOCAL_MODULE := libJNItest
    LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog 
    
    LOCAL_SRC_FILES := \
             src/testjni.cpp
    
    include $(BUILD_SHARED_LIBRARY)
    include $(CLEAR_VARS)
    

    And the logcat error :

    INFO/testjni(9387): JNI INIT
    07-05 15:35:16.993: INFO/onCreate(9387): Native function begining
    07-05 15:35:16.993: INFO/testjni(9387): JNI work !
    07-05 15:35:17.003: WARN/dalvikvm(9387): JNI WARNING: can't call Lcom/test/jnitest/JNITestActivity;.callFromCPP on instance of Ljava/lang/Class;
    07-05 15:35:17.003: INFO/dalvikvm(9387): "main" prio=5 tid=1 RUNNABLE
    07-05 15:35:17.018: INFO/dalvikvm(9387):   | group="main" sCount=0 dsCount=0 obj=0x4001f1a8 self=0xce48
    07-05 15:35:17.018: INFO/dalvikvm(9387):   | sysTid=9387 nice=0 sched=0/0 cgrp=default handle=-1345006528
    07-05 15:35:17.023: INFO/dalvikvm(9387):   | schedstat=( 219631994 557413541 53 )
    07-05 15:35:17.023: INFO/dalvikvm(9387):   at com.test.jnitest.JNITestActivity.javaCallJNI(Native Method)
    07-05 15:35:17.023: INFO/dalvikvm(9387):   at com.test.jnitest.JNITestActivity.onCreate(JNITestActivity.java:23)
    07-05 15:35:17.023: INFO/dalvikvm(9387):   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
    07-05 15:35:17.048: INFO/dalvikvm(9387):   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
    07-05 15:35:17.053: INFO/dalvikvm(9387):   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
    07-05 15:35:17.053: INFO/dalvikvm(9387):   at android.app.ActivityThread.access$1500(ActivityThread.java:117)
    07-05 15:35:17.053: INFO/dalvikvm(9387):   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
    07-05 15:35:17.053: INFO/dalvikvm(9387):   at android.os.Handler.dispatchMessage(Handler.java:99)
    07-05 15:35:17.053: INFO/dalvikvm(9387):   at android.os.Looper.loop(Looper.java:123)
    07-05 15:35:17.053: INFO/dalvikvm(9387):   at android.app.ActivityThread.main(ActivityThread.java:3683)
    07-05 15:35:17.053: INFO/dalvikvm(9387):   at java.lang.reflect.Method.invokeNative(Native Method)
    07-05 15:35:17.053: INFO/dalvikvm(9387):   at java.lang.reflect.Method.invoke(Method.java:507)
    07-05 15:35:17.053: INFO/dalvikvm(9387):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
    07-05 15:35:17.053: INFO/dalvikvm(9387):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
    07-05 15:35:17.053: INFO/dalvikvm(9387):   at dalvik.system.NativeStart.main(Native Method)
    07-05 15:35:17.053: ERROR/dalvikvm(9387): VM aborting
    07-05 15:35:17.163: INFO/DEBUG(31): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
    07-05 15:35:17.163: INFO/DEBUG(31): Build fingerprint: 'generic/sdk/generic:2.3.3/GRI34/101070:eng/test-keys'
    07-05 15:35:17.163: INFO/DEBUG(31): pid: 9387, tid: 9387  >>> com.test.jnitest <<<
    07-05 15:35:17.173: INFO/DEBUG(31): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadd00d
    07-05 15:35:17.173: INFO/DEBUG(31):  r0 fffffec4  r1 deadd00d  r2 00000026  r3 00000000
    07-05 15:35:17.183: INFO/DEBUG(31):  r4 800a45c0  r5 40517438  r6 41ad8ad0  r7 40517438
    07-05 15:35:17.183: INFO/DEBUG(31):  r8 befc3428  r9 418fccdc  10 418fccc8  fp 42598bb8
    07-05 15:35:17.193: INFO/DEBUG(31):  ip 800a4720  sp befc3398  lr afd19375  pc 80045a4a  cpsr 20000030
    07-05 15:35:17.453: INFO/DEBUG(31):          #00  pc 00045a4a  /system/lib/libdvm.so
    07-05 15:35:17.453: INFO/DEBUG(31):          #01  pc 00037748  /system/lib/libdvm.so
    07-05 15:35:17.463: INFO/DEBUG(31):          #02  pc 0003dc44  /system/lib/libdvm.so
    07-05 15:35:17.473: INFO/DEBUG(31):          #03  pc 0003fa9c  /system/lib/libdvm.so
    07-05 15:35:17.473: INFO/DEBUG(31):          #04  pc 000003f2  /data/data/com.test.jnitest/lib/libJNItest.so
    07-05 15:35:17.473: INFO/DEBUG(31):          #05  pc 00000440  /data/data/com.test.jnitest/lib/libJNItest.so
    07-05 15:35:17.473: INFO/DEBUG(31):          #06  pc 00017d74  /system/lib/libdvm.so
    07-05 15:35:17.483: INFO/DEBUG(31):          #07  pc 00048ecc  /system/lib/libdvm.so
    07-05 15:35:17.493: INFO/DEBUG(31):          #08  pc 00041a86  /system/lib/libdvm.so
    07-05 15:35:17.493: INFO/DEBUG(31):          #09  pc 0004e624  /system/lib/libdvm.so
    07-05 15:35:17.503: INFO/DEBUG(31):          #10  pc 0001cfd4  /system/lib/libdvm.so
    07-05 15:35:17.503: INFO/DEBUG(31):          #11  pc 000220dc  /system/lib/libdvm.so
    07-05 15:35:17.503: INFO/DEBUG(31):          #12  pc 00020fd0  /system/lib/libdvm.so
    07-05 15:35:17.523: INFO/DEBUG(31):          #13  pc 0005f5de  /system/lib/libdvm.so
    07-05 15:35:17.523: INFO/DEBUG(31):          #14  pc 00066fce  /system/lib/libdvm.so
    07-05 15:35:17.523: INFO/DEBUG(31):          #15  pc 0001cfd4  /system/lib/libdvm.so
    07-05 15:35:17.533: INFO/DEBUG(31):          #16  pc 000220dc  /system/lib/libdvm.so
    07-05 15:35:17.543: INFO/DEBUG(31):          #17  pc 00020fd0  /system/lib/libdvm.so
    07-05 15:35:17.543: INFO/DEBUG(31):          #18  pc 0005f430  /system/lib/libdvm.so
    07-05 15:35:17.553: INFO/DEBUG(31):          #19  pc 0004b9a8  /system/lib/libdvm.so
    07-05 15:35:17.553: INFO/DEBUG(31):          #20  pc 0003ebb0  /system/lib/libdvm.so
    07-05 15:35:17.563: INFO/DEBUG(31):          #21  pc 000314ac  /system/lib/libandroid_runtime.so
    07-05 15:35:17.573: INFO/DEBUG(31):          #22  pc 000322c6  /system/lib/libandroid_runtime.so
    07-05 15:35:17.573: INFO/DEBUG(31):          #23  pc 00008ca2  /system/bin/app_process
    07-05 15:35:17.573: INFO/DEBUG(31):          #24  pc 00014db8  /system/lib/libc.so
    07-05 15:35:17.573: INFO/DEBUG(31): code around pc:
    07-05 15:35:17.583: INFO/DEBUG(31): 80045a28 447a4479 ed0cf7d1 20004c09 ee34f7d1 
    07-05 15:35:17.583: INFO/DEBUG(31): 80045a38 447c4808 6bdb5823 d0002b00 49064798 
    07-05 15:35:17.593: INFO/DEBUG(31): 80045a48 700a2226 eea0f7d1 000436b7 00045275 
    07-05 15:35:17.593: INFO/DEBUG(31): 80045a58 0005eb82 fffffec4 deadd00d b510b40e 
    07-05 15:35:17.604: INFO/DEBUG(31): 80045a68 4c0a4b09 447bb083 aa05591b 6b5bca02 
    07-05 15:35:17.604: INFO/DEBUG(31): code around lr:
    07-05 15:35:17.633: INFO/DEBUG(31): afd19354 b0834a0d 589c447b 26009001 686768a5 
    07-05 15:35:17.633: INFO/DEBUG(31): afd19364 220ce008 2b005eab 1c28d003 47889901 
    07-05 15:35:17.633: INFO/DEBUG(31): afd19374 35544306 d5f43f01 2c006824 b003d1ee 
    07-05 15:35:17.633: INFO/DEBUG(31): afd19384 bdf01c30 000281a8 ffffff88 1c0fb5f0 
    07-05 15:35:17.643: INFO/DEBUG(31): afd19394 43551c3d a904b087 1c16ac01 604d9004 
    07-05 15:35:17.643: INFO/DEBUG(31): stack:
    07-05 15:35:17.643: INFO/DEBUG(31):     befc3358  00000015  
    07-05 15:35:17.643: INFO/DEBUG(31):     befc335c  afd18407  /system/lib/libc.so
    07-05 15:35:17.653: INFO/DEBUG(31):     befc3360  afd4270c  /system/lib/libc.so
    07-05 15:35:17.653: INFO/DEBUG(31):     befc3364  afd426b8  /system/lib/libc.so
    07-05 15:35:17.653: INFO/DEBUG(31):     befc3368  00000000  
    07-05 15:35:17.653: INFO/DEBUG(31):     befc336c  afd19375  /system/lib/libc.so
    07-05 15:35:17.653: INFO/DEBUG(31):     befc3370  0000ce48  [heap]
    07-05 15:35:17.663: INFO/DEBUG(31):     befc3374  afd183d9  /system/lib/libc.so
    07-05 15:35:17.663: INFO/DEBUG(31):     befc3378  40517438  /dev/ashmem/dalvik-heap (deleted)
    07-05 15:35:17.673: INFO/DEBUG(31):     befc337c  0005eb82  [heap]
    07-05 15:35:17.673: INFO/DEBUG(31):     befc3380  40517438  /dev/ashmem/dalvik-heap (deleted)
    07-05 15:35:17.673: INFO/DEBUG(31):     befc3384  41ad8ad0  /dev/ashmem/dalvik-LinearAlloc (deleted)
    07-05 15:35:17.673: INFO/DEBUG(31):     befc3388  40517438  /dev/ashmem/dalvik-heap (deleted)
    07-05 15:35:17.673: INFO/DEBUG(31):     befc338c  afd18437  /system/lib/libc.so
    07-05 15:35:17.673: INFO/DEBUG(31):     befc3390  df002777  
    07-05 15:35:17.673: INFO/DEBUG(31):     befc3394  e3a070ad  
    07-05 15:35:17.673: INFO/DEBUG(31): #00 befc3398  40009328  /dev/ashmem/dalvik-heap (deleted)
    07-05 15:35:17.683: INFO/DEBUG(31):     befc339c  8003774d  /system/lib/libdvm.so
    07-05 15:35:17.683: INFO/DEBUG(31): #01 befc33a0  40009328  /dev/ashmem/dalvik-heap (deleted)
    07-05 15:35:17.693: INFO/DEBUG(31):     befc33a4  8003dc49  /system/lib/libdvm.so
    07-05 15:35:19.693: DEBUG/Zygote(33): Process 9387 terminated by signal (11)
    07-05 15:35:19.713: INFO/ActivityManager(74): Process com.test.jnitest (pid 9387) has died.
    

    Thank you, Christophe.

    • Maximus
      Maximus almost 13 years
      Could you post that actual logcat error? Since you're not registering your native method though the JNI_OnLoad (which is optional) it may just be due to that. Also, is it your Logged "FindClass error" you are seeing or something else?
    • Crisic
      Crisic almost 13 years
      Thank you for your response, I edit my previous post to include the logcat of the error.
    • John
      John over 9 years
      It looks like the title is wrong, where is the call of java method from c? All I can see is you calling C from Java.
  • Crisic
    Crisic almost 13 years
    With the fix of this update and the adding of JNI_Onload function in the export "C", I get this exception: java.lang.NoSuchMethodError: callFromCPP
  • Viktor Apoyan
    Viktor Apoyan over 12 years
    but if I have no obj how I can do this ?
  • Maximus
    Maximus over 12 years
    obj is coming into from the method/function parameters. Every jni function's first 2 parameters are JNIEnv* env, jobject obj. For static methods the second parameter is usually jclass thiz.