Search code examples
eclipseubuntuopenclunsatisfiedlinkerrorarrayfire

Exception Ljava/lang/UnsatisfiedLinkError


I am currently trying to build and run this project: https://github.com/arrayfire/androidcl on the AT&T Samsung Galaxy S3. The problem is when I try running: ./ndk-build -C ~/Desktop/ArrayFire/androidcl/jni

Then I try to run it on the phone by going to "Run -> Run as -> Android Application."

I get an "Unfortunately, droidcl has stopped working." I am quite the noob, but after days of researching, I think it has to do with the NDK. On line 19 at LiveFeatureActivity, "System.loadLibrary("JNIProcessor");" is my biggest suspicion.

All the files are on Git. Help would be appreciated as I tried to run it for 3 days but to no avail.

Here is what ndk-build says:

./ndk-build -C ~/Desktop/ArrayFire/androidcl/jni
Android NDK: WARNING:/home/laptop/Desktop/ArrayFire/androidcl/jni/Android.mk:JNIProcessor: non-system libraries in linker flags: /usr/lib/libOpenCL.so    
Android NDK:     This is likely to result in incorrect builds. Try using LOCAL_STATIC_LIBRARIES    
Android NDK:     or LOCAL_SHARED_LIBRARIES instead to list the library dependencies of the    
Android NDK:     current module    
make: Entering directory `/home/laptop/Desktop/ArrayFire/androidcl/jni'
[armeabi] Compile++ arm  : JNIProcessor <= processor.cpp
[armeabi] SharedLibrary  : libJNIProcessor.so
arm-linux-androideabi-g++: error: /usr/lib/libOpenCL.so: No such file or directory
make: *** [/home/laptop/Desktop/ArrayFire/androidcl/obj/local/armeabi/libJNIProcessor.so] Error 1
make: Leaving directory `/home/laptop/Desktop/ArrayFire/androidcl/jni'

Here is the Android.mk:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := JNIProcessor
LOCAL_ARM_MODE := arm
LOCAL_SRC_FILES := processor.cpp
LOCAL_CPPFLAGS	:= -DARM -DOS_LNX -DARCH_32 -fexceptions
LOCAL_CPPFLAGS	+= -I$(LOCAL_PATH)/include
LOCAL_CPPFLAGS 	+= -fexceptions
LOCAL_LDLIBS := -ljnigraphics -llog $(LOCAL_PATH)/libs/libOpenCL.so
include $(BUILD_SHARED_LIBRARY) 

I tried going into the Android.mk file and pointing directly to /usr/lib/libOpenCl.so (which after checking the library is there) but still doesn't work.

Here is the logcat file:

02-06 22:52:27.515: D/ActivityThread(3233): setTargetHeapUtilization:0.25
02-06 22:52:27.515: D/ActivityThread(3233): setTargetHeapIdealFree:8388608
02-06 22:52:27.515: D/ActivityThread(3233): setTargetHeapConcurrentStart:2097152
02-06 22:52:27.575: W/dalvikvm(3233): Exception Ljava/lang/UnsatisfiedLinkError; thrown while initializing Lcom/example/LiveFeatureActivity;
02-06 22:52:27.575: W/dalvikvm(3233): Class init failed in newInstance call (Lcom/example/LiveFeatureActivity;)
02-06 22:52:27.575: D/AndroidRuntime(3233): Shutting down VM
02-06 22:52:27.575: W/dalvikvm(3233): threadid=1: thread exiting with uncaught exception (group=0x40cb6300)
02-06 22:52:27.575: E/AndroidRuntime(3233): FATAL EXCEPTION: main
02-06 22:52:27.575: E/AndroidRuntime(3233): java.lang.ExceptionInInitializerError
02-06 22:52:27.575: E/AndroidRuntime(3233): 	at java.lang.Class.newInstanceImpl(Native Method)
02-06 22:52:27.575: E/AndroidRuntime(3233): 	at java.lang.Class.newInstance(Class.java:1319)
02-06 22:52:27.575: E/AndroidRuntime(3233): 	at android.app.Instrumentation.newActivity(Instrumentation.java:1053)
02-06 22:52:27.575: E/AndroidRuntime(3233): 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2090)
02-06 22:52:27.575: E/AndroidRuntime(3233): 	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2210)
02-06 22:52:27.575: E/AndroidRuntime(3233): 	at android.app.ActivityThread.access$600(ActivityThread.java:142)
02-06 22:52:27.575: E/AndroidRuntime(3233): 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1208)
02-06 22:52:27.575: E/AndroidRuntime(3233): 	at android.os.Handler.dispatchMessage(Handler.java:99)
02-06 22:52:27.575: E/AndroidRuntime(3233): 	at android.os.Looper.loop(Looper.java:137)
02-06 22:52:27.575: E/AndroidRuntime(3233): 	at android.app.ActivityThread.main(ActivityThread.java:4931)
02-06 22:52:27.575: E/AndroidRuntime(3233): 	at java.lang.reflect.Method.invokeNative(Native Method)
02-06 22:52:27.575: E/AndroidRuntime(3233): 	at java.lang.reflect.Method.invoke(Method.java:511)
02-06 22:52:27.575: E/AndroidRuntime(3233): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
02-06 22:52:27.575: E/AndroidRuntime(3233): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:558)
02-06 22:52:27.575: E/AndroidRuntime(3233): 	at dalvik.system.NativeStart.main(Native Method)
02-06 22:52:27.575: E/AndroidRuntime(3233): Caused by: java.lang.UnsatisfiedLinkError: Couldn't load JNIProcessor: findLibrary returned null
02-06 22:52:27.575: E/AndroidRuntime(3233): 	at java.lang.Runtime.loadLibrary(Runtime.java:365)
02-06 22:52:27.575: E/AndroidRuntime(3233): 	at java.lang.System.loadLibrary(System.java:535)
02-06 22:52:27.575: E/AndroidRuntime(3233): 	at com.example.LiveFeatureActivity.<clinit>(LiveFeatureActivity.java:19)
02-06 22:52:27.575: E/AndroidRuntime(3233): 	... 15 more
02-06 22:52:43.723: I/Process(3233): Sending signal. PID: 3233 SIG: 9


Solution

  • The UnsatisfiedLinkError you receive when running the app is simply because your module failed to build, and therefore wasn't included in the app. Getting the NDK build to link against a libOpenCL.so should solve this.

    You first need to acquire a libOpenCL.so to link against, which you should be able to find on the target device (if it isn't there, then this application won't work anyway). On my devices, the OpenCL library is in /system/vendor/lib/libOpenCL.so, but you may need to poke around with adb shell to find it. To copy it to your local machine run adb pull /system/vendor/lib/libOpenCL.so.

    If you put this library in your jni/ directory, then you should just need to have libOpenCL.so in your LOCAL_LDLIBS variable. Otherwise, I usually just stick a copy of this library in the NDK platform directory (e.g. $NDK_DIR/platforms/android-17/arch-arm/usr/lib/), and then it is available to all applications to use by adding -lOpenCL to your LOCAL_LDLIBS variable. In both cases, you'll probably get a warning about non-system libraries in your linker flags, but these should be safe to ignore.