Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 846
Crisic Avatar asked Jul 05 '11 14:07

Crisic


2 Answers

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 ;)

like image 192
Crisic Avatar answered Nov 20 '22 07:11

Crisic


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);
like image 4
Maximus Avatar answered Nov 20 '22 07:11

Maximus