Question

I created a very simple modified HelloJni application based on HelloJni sample. I use NDK r10 on windows (android-ndk32-r10-windows-x86_64.zip package). This modified application works fine in case of ARM devices but I get UnsatisfiedLinkError testing on Samsung Galaxy Tab 3 with Intel Atom CPU. Examined the lib using i686-linux-android-gcc-nm.exe also looks to be fine. (Original sample HelloJni project works fine on both ARM and x86.)

Logcat:

08-01 09:25:43.409: D/dalvikvm(5277): Trying to load lib /data/app-lib/com.test.hls1/libdrm.so 0x420aceb0
08-01 09:25:43.409: D/dalvikvm(5277): Added shared lib /data/app-lib/com.test.hls1/libdrm.so 0x420aceb0
08-01 09:25:43.409: D/dalvikvm(5277): No JNI_OnLoad found in /data/app-lib/com.test.hls-1/libdrm.so 0x420aceb0, skipping init
08-01 09:25:43.409: I/Drm(5277): lib loaded
08-01 09:25:43.409: W/dalvikvm(5277): No implementation found for native Lcom/test/hls/Drm;.stringFromJNI:()Ljava/lang/String;
08-01 09:25:43.409: D/AndroidRuntime(5277): Shutting down VM
08-01 09:25:43.409: W/dalvikvm(5277): threadid=1: thread exiting with uncaught exception (group=0x41ab7e10)
08-01 09:25:43.419: E/AndroidRuntime(5277): FATAL EXCEPTION: main
08-01 09:25:43.419: E/AndroidRuntime(5277): java.lang.UnsatisfiedLinkError: Native method not found: com.test.hls.Drm.stringFromJNI:()Ljava/lang/String;
08-01 09:25:43.419: E/AndroidRuntime(5277): at com.test.hls.Drm.stringFromJNI(Native Method)
08-01 09:25:43.419: E/AndroidRuntime(5277): at com.test.hls.Main.onCreate(Main.java:36)
08-01 09:25:43.419: E/AndroidRuntime(5277): at android.app.Activity.performCreate(Activity.java:5267)
08-01 09:25:43.419: E/AndroidRuntime(5277): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1097)
08-01 09:25:43.419: E/AndroidRuntime(5277): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2209)
08-01 09:25:43.419: E/AndroidRuntime(5277): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2295)
08-01 09:25:43.419: E/AndroidRuntime(5277): at android.app.ActivityThread.access$700(ActivityThread.java:150)
08-01 09:25:43.419: E/AndroidRuntime(5277): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1280)
08-01 09:25:43.419: E/AndroidRuntime(5277): at android.os.Handler.dispatchMessage(Handler.java:99)
08-01 09:25:43.419: E/AndroidRuntime(5277): at android.os.Looper.loop(Looper.java:176)
08-01 09:25:43.419: E/AndroidRuntime(5277): at android.app.ActivityThread.main(ActivityThread.java:5279)
08-01 09:25:43.419: E/AndroidRuntime(5277): at java.lang.reflect.Method.invokeNative(Native Method)
08-01 09:25:43.419: E/AndroidRuntime(5277): at java.lang.reflect.Method.invoke(Method.java:511)
08-01 09:25:43.419: E/AndroidRuntime(5277): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
08-01 09:25:43.419: E/AndroidRuntime(5277): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
08-01 09:25:43.419: E/AndroidRuntime(5277): at dalvik.system.NativeStart.main(Native Method)
08-01 09:25:43.429: W/ContextImpl(2295): Calling a method in the system process without a qualified user: android.app.ContextImpl.sendBroadcast:1375 com.android.server.am.ActivityStack.startPausingLocked:1418 com.android.server.am.ActivityStack.finishActivityLocked:5925 com.android.server.am.ActivityStack.finishActivityLocked:5839 com.android.server.am.ActivityManagerService.handleAppCrashLocked:9563 
08-01 09:25:43.459: I/dumpstate(5292): begin
08-01 09:25:43.749: E/android.os.Debug(2295): !@Dumpstate > sdumpstate -k -t -z -d -o /data/log/dumpstate_app_error

Main.java:

package com.test.hls;

import android.app.Activity;
import android.widget.TextView;
import android.os.Bundle;

public class Main extends Activity
{
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        TextView  tv = new TextView(this);
        tv.setText( new Drm().stringFromJNI() );
        setContentView(tv);
    }
} 

Drm.java:

package com.test.hls;

import android.util.Log;

public class Drm {
     public native String stringFromJNI();

     static {
         System.loadLibrary("drm");
         Log.i("Drm", "lib loaded");
     }
}

drm.c:

#include <string.h>
#include <jni.h>

jstring
Java_com_test_hls_Drm_stringFromJNI( JNIEnv* env,
                                              jobject thiz )
{
#if defined(__arm__)
  #if defined(__ARM_ARCH_7A__)
    #if defined(__ARM_NEON__)
      #if defined(__ARM_PCS_VFP)
        #define ABI "armeabi-v7a/NEON (hard-float)"
      #else
        #define ABI "armeabi-v7a/NEON"
      #endif
    #else
      #if defined(__ARM_PCS_VFP)
        #define ABI "armeabi-v7a (hard-float)"
      #else
        #define ABI "armeabi-v7a"
      #endif
    #endif
  #else
   #define ABI "armeabi"
  #endif
#elif defined(__i386__)
   #define ABI "x86"
#elif defined(__x86_64__)
   #define ABI "x86_64"
#elif defined(__mips64)  /* mips64el-* toolchain defines __mips__ too */
   #define ABI "mips64"
#elif defined(__mips__)
   #define ABI "mips"
#elif defined(__aarch64__)
   #define ABI "arm64-v8a"
#else
   #define ABI "unknown"
#endif
    return (*env)->NewStringUTF(env, "Hello from JNI !  Compiled with ABI " ABI ".");
} 

Andoid.mk:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := drm
LOCAL_SRC_FILES := drm.c

include $(BUILD_SHARED_LIBRARY)

i686-linux-android-gcc-nm.exe output for libs/x86/libdrm.so

00000390 r .LC0
00002010 A __bss_start
         U __cxa_atexit
         U __cxa_finalize
0000200c d __dso_handle
00000468 r __FRAME_END__
00000330 t __on_dlclose
         U __stack_chk_fail
00000310 t __stack_chk_fail_local
00000354 t __x86.get_pc_thunk.bx
00001efc d _DYNAMIC
00002010 A _edata
00002010 A _end
00001ff4 d _GLOBAL_OFFSET_TABLE_
000002d0 t atexit
00000360 T Java_com_test_hls_Drm_stringFromJNI

Do you have any idea what can cause this issue? Thanks

Was it helpful?

Solution

I solved it. The problem is the "drm" library name. Intel devices may have other libdrm on library path (I think it is the Direct Rendering Manager graphics library). So my locale module name causes naming collision and other lib was found by DVM first. Choosing other name it works fine on x86 test device as well.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top