onJNILoad not being called when calling System.loadLibrary - android

I have add a print log statement in JNI_OnLoad, but I found that it is not being called. Here is my JNI_OnLoad method.
extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
__android_log_print(ANDROID_LOG_INFO, __FUNCTION__, "onLoad");
// some init code
}
Do I need to declare JNI_OnLoad in a specific file or declare sth in Android.MK tells system where to find the JNI_OnLoad method? Now I just put to one of the many .cpp files.
compiled .so lib is attached. I try to dump the so file, and I am sure the JNI_OnLoad method is exported.
https://docs.google.com/file/d/0B089WeEZXTb3ZjZiQllaYThuUUk/edit
Actually, I am trying to port a library from android source (libcorejava.so). To avoid class path conflict, I already change the class path.
And here is the file that declares JNI_OnLoad:
https://android.googlesource.com/platform/libcore/+/master/luni/src/main/native/Register.cpp
I already change the signature to the above one in order to match the standard signature
EDIT:
I found that android source does not load it by System.loadLibrary! It says libcorejava is used to implement System.loadLibrary, so we cannot use System.loadLibrary to load it. But in my case, it should not be a problem as I only need part of the function (ICU related).
https://android.googlesource.com/platform/dalvik/+/master/vm/Init.cpp
// Most JNI libraries can just use System.loadLibrary, but you can't
// if you're the library that implements System.loadLibrary!
loadJniLibrary("javacore");
loadJniLibrary("nativehelper");
EDIT 2:
It turns out that it is because the name conflict of the library!
But it seems that libjavacore requires other library. Does there any tool that can list out what the dependency I am missing?
java.lang.UnsatisfiedLinkError: Cannot load library: reloc_library[1286]: XXX
EDIT 3:
TextClock is a new api for displaying time. It only exists in 4.2+ api up. I am trying to backport it so that older sdk can uses it. It depends on a ICU library which resides in libjavacore. So I modify the Android.mk file to make sure the libjavacore only include the icu related source file and the final compiled so file is being included in my apk.
TextClock:
http://developer.android.com/reference/android/widget/TextClock.html
It now works in the phone which originally support TextClock, but doesn't work in old devices. Here is the exception log. I think it is because libjavacore is the wrapper of ICU library. Apart from the wrapper, I still need to port the ICU library. But I am going to give up as the size of ICU library is quite large and seems doesn't worth for it...
12-13 14:07:54.859: E/AndroidRuntime(2091): java.lang.UnsatisfiedLinkError: Cannot load library: reloc_library[1306]: 36 cannot locate '_ZN6icu_516Locale14createFromNameEPKc'...
12-13 14:07:54.859: E/AndroidRuntime(2091): at java.lang.Runtime.loadLibrary(Runtime.java:370)
12-13 14:07:54.859: E/AndroidRuntime(2091): at java.lang.System.loadLibrary(System.java:535)
12-13 14:07:54.859: E/AndroidRuntime(2091): at com.example.time.MainActivity.onCreate(MainActivity.java:20)
12-13 14:07:54.859: E/AndroidRuntime(2091): at android.app.Activity.performCreate(Activity.java:5008)
12-13 14:07:54.859: E/AndroidRuntime(2091): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
12-13 14:07:54.859: E/AndroidRuntime(2091): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
12-13 14:07:54.859: E/AndroidRuntime(2091): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
12-13 14:07:54.859: E/AndroidRuntime(2091): at android.app.ActivityThread.access$600(ActivityThread.java:130)
12-13 14:07:54.859: E/AndroidRuntime(2091): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
12-13 14:07:54.859: E/AndroidRuntime(2091): at android.os.Handler.dispatchMessage(Handler.java:99)
12-13 14:07:54.859: E/AndroidRuntime(2091): at android.os.Looper.loop(Looper.java:137)
12-13 14:07:54.859: E/AndroidRuntime(2091): at android.app.ActivityThread.main(ActivityThread.java:4745)
12-13 14:07:54.859: E/AndroidRuntime(2091): at java.lang.reflect.Method.invokeNative(Native Method)
12-13 14:07:54.859: E/AndroidRuntime(2091): at java.lang.reflect.Method.invoke(Method.java:511)
12-13 14:07:54.859: E/AndroidRuntime(2091): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
12-13 14:07:54.859: E/AndroidRuntime(2091): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
12-13 14:07:54.859: E/AndroidRuntime(2091): at dalvik.system.NativeStart.main(Native Method)

You can dump the symbols in your .so file using readelf in your toolchains folder. Check to see that JNI_OnLoad is exported. The -s (symbols) command and the name of the .so file in your libs folder should do it.

In older releases of Android, the library was linked directly into the VM (libdvm.so linked against libnativehelper.so which linked against libjavacore.a). In recent releases this changed to always load the library at start time, using the internal native library load mechanism, so JNI_OnLoad will be called if present.
If I run adb shell dalvikvm Foo (where "Foo" doesn't exist), I see this in logcat:
D dalvikvm: Trying to load lib libjavacore.so 0x0
D dalvikvm: Added shared lib libjavacore.so 0x0
D dalvikvm: Trying to load lib libnativehelper.so 0x0
D dalvikvm: Added shared lib libnativehelper.so 0x0
D dalvikvm: No JNI_OnLoad found in libnativehelper.so 0x0, skipping init
So it loaded libjavacore.so and apparently found and ran JNI_OnLoad (no news is good news). It loaded libnativehelper.so and didn't find a JNI_OnLoad, so it logged a message to tell you so in case you were expecting otherwise.
If you replace the libjavacore.so in /system/lib (on a rooted device), and run the dalvikvm command, you should see your message in the log file, mixed in with messages like I've shown above. If you restart the system, you should see your message during zygote startup, and not again unless something runs a Dalvik-based command (like am).

Related

Current AndroidStudio sample fails on phone due to runtime native library link error. Why?

Its on an HTC Aria, running 2.2 (API 8)
https://en.wikipedia.org/wiki/HTC_Aria
The aria is an armv6 device that supports opengles 2
If you open up the latest Android Studio (im working on windows 7), then import the HelloGL2 sample, then simply try to run it on the above device, it will fail as soon as it tries to make a call into the native library.
Here is the log:
01-06 11:14:08.467 12771-12813/com.android.gl2jni D/dalvikvm: Trying to load lib /data/data/com.android.gl2jni/lib/libgl2jni.so 0x44c165d0
01-06 11:14:08.467 12771-12813/com.android.gl2jni I/dalvikvm: Unable to dlopen(/data/data/com.android.gl2jni/lib/libgl2jni.so): Cannot load library: link_image[1995]: failed to link libgl2jni.so
01-06 11:14:08.477 12771-12813/com.android.gl2jni W/dalvikvm: Exception Ljava/lang/UnsatisfiedLinkError; thrown during Lcom/android/gl2jni/GL2JNILib;.<clinit>
01-06 11:14:08.497 12771-12813/com.android.gl2jni W/dalvikvm: threadid=8: thread exiting with uncaught exception (group=0x40028a00)
01-06 11:14:08.517 95-121/? I/ActivityManager: Displayed activity com.android.gl2jni/.GL2JNIActivity: 9823 ms (total 2027818 ms)
01-06 11:14:08.567 12771-12813/com.android.gl2jni E/AndroidRuntime: FATAL EXCEPTION: GLThread 9
java.lang.ExceptionInInitializerError
at com.android.gl2jni.GL2JNIView$Renderer.onSurfaceChanged(GL2JNIView.java:332)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1327)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1118)
Caused by: java.lang.UnsatisfiedLinkError: Library gl2jni not found
at java.lang.Runtime.loadLibrary(Runtime.java:461)
at java.lang.System.loadLibrary(System.java:557)
at com.android.gl2jni.GL2JNILib.<clinit>(GL2JNILib.java:24)
at com.android.gl2jni.GL2JNIView$Renderer.onSurfaceChanged(GL2JNIView.java:332) 
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1327) 
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1118) 
01-06 11:14:08.607 95-164/? W/ActivityManager: Force finishing activity com.android.gl2jni/.GL2JNIActivity
This sample works on the 3 other devices i've tried (Galaxy s5, Galaxy J1, Nexus s)
The line: 'Unable to dlopen(/data/data/com.android.gl2jni/lib/libgl2jni.so): Cannot load library: link_image[1995]: failed to link libgl2jni.so' is probably key. I tried loading the library explicitly using system.loadlibrary, but the same problem happens on that call.
I think it might be something to do with the processor being armv6?
The sample is configured to do 'armeabi' though.

Eclipse and "Installation failed due to invalid APK file"

I am combining OpenCV with tess-two to make an Android OCR application. It worked perfectly well with OpenCV4Android + custom JNI OpenCV libraries, until I started importing tess-two library. It compiles but does not install:
[2015-08-02 14:43:02 - OpenCV Tutorial 2 - Mixed Processing] Installation failed due to invalid APK file!
[2015-08-02 14:43:02 - OpenCV Tutorial 2 - Mixed Processing] Please check logcat output for more details.
[2015-08-02 14:43:02 - OpenCV Tutorial 2 - Mixed Processing] Launch canceled!
Other posts suggest it's library and reference errors. Indeed, it can install again when I remove ..\tess-two in Properties->Android->Library. Also the tess-two library is compiled correctly, because I sueccesfully compiled and an example project.
And here is the logcat.
08-02 14:46:07.775: D/AndroidRuntime(14699): >>>>>> AndroidRuntime START com.android.internal.os.RuntimeInit <<<<<<
08-02 14:46:07.775: D/AndroidRuntime(14699): CheckJNI is OFF
08-02 14:46:07.785: D/dalvikvm(14699): Trying to load lib libjavacore.so 0x0
08-02 14:46:07.795: D/dalvikvm(14699): Added shared lib libjavacore.so 0x0
08-02 14:46:07.805: D/dalvikvm(14699): Trying to load lib libnativehelper.so 0x0
08-02 14:46:07.805: D/dalvikvm(14699): Added shared lib libnativehelper.so 0x0
08-02 14:46:07.835: E/cutils-trace(14699): Error opening trace file: No such file or directory (2)
08-02 14:46:08.005: D/AndroidRuntime(14699): Calling main entry com.android.commands.pm.Pm
08-02 14:46:08.015: D/zipro(9906): Zip: EOCD not found, /data/local/tmp/OpenCV Tutorial 2 - Mixed Processing.apk is not zip
08-02 14:46:08.015: D/asset(9906): failed to open Zip archive '/data/local/tmp/OpenCV Tutorial 2 - Mixed Processing.apk'
08-02 14:46:08.015: W/PackageParser(9906): Unable to read AndroidManifest.xml of /data/local/tmp/OpenCV Tutorial 2 - Mixed Processing.apk
08-02 14:46:08.015: W/PackageParser(9906): java.io.FileNotFoundException: AndroidManifest.xml
08-02 14:46:08.015: W/PackageParser(9906): at android.content.res.AssetManager.openXmlAssetNative(Native Method)
08-02 14:46:08.015: W/PackageParser(9906): at android.content.res.AssetManager.openXmlBlockAsset(AssetManager.java:522)
08-02 14:46:08.015: W/PackageParser(9906): at android.content.res.AssetManager.openXmlResourceParser(AssetManager.java:478)
08-02 14:46:08.015: W/PackageParser(9906): at android.content.pm.PackageParser.parsePackageLite(PackageParser.java:787)
08-02 14:46:08.015: W/PackageParser(9906): at com.android.defcontainer.DefaultContainerService$1.getMinimalPackageInfo(DefaultContainerService.java:174)
08-02 14:46:08.015: W/PackageParser(9906): at com.android.internal.app.IMediaContainerService$Stub.onTransact(IMediaContainerService.java:110)
08-02 14:46:08.015: W/PackageParser(9906): at android.os.Binder.execTransact(Binder.java:388)
08-02 14:46:08.015: W/PackageParser(9906): at dalvik.system.NativeStart.run(Native Method)
08-02 14:46:08.015: W/DefContainer(9906): Failed to parse package
08-02 14:46:08.025: W/ActivityManager(455): No content provider found for permission revoke: file:///data/local/tmp/OpenCV Tutorial 2 - Mixed Processing.apk
I added
<uses-sdk android:minSdkVersion="11"
android:targetSdkVersion="15"/>
to AndroidManifest.xml in both the project and the tess-two library. Everything worked.

RenderScript No JNI_OnLoad found error

I am using renderscript library in my project and I perfectly run my apk on Samsung S4 I9500. But when I tried this in other phones I get crash.
No JNI_OnLoad found in /system/lib/libRSSupport.so 0x4185f0f0, skipping init
02-23 19:42:40.370 8994-8994/com.example.gameboy.gununtesti E/dalvikvm﹕ ERROR: couldn't find native method
02-23 19:42:40.370 8994-8994/com.example.gameboy.gununtesti E/dalvikvm﹕ Requested: Landroid/support/v8/renderscript/RenderScript;._nInit:()V
02-23 19:42:40.370 8994-8994/com.example.gameboy.gununtesti E/JNIHelp﹕ RegisterNatives failed for 'android/support/v8/renderscript/RenderScript', aborting
02-23 19:42:40.370 8994-8994/com.example.gameboy.gununtesti A/libc﹕ Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1), thread 8994
Any help appreciated. Thanks.
You forgot to include libRSSupport.so + the other native libraries in your .apk. This is attempting to load the system version of the compatibility, library, which will not work with your app.

Unable to load native library when running titanium android app

I'm building an Android app using Titanium.
My Android module com.tgl.androidmodule includes a native lib called libAlibrary-jni.so.
In my .apk, the native libs are present in their correct folders (lib/armeabi, lib/armeabi-v7a, lib/x86) but I still get an error when trying to load the library dynamically :System.loadLibrary("Alibrary-jni");
Here is the full stacktrace of the error:
11-12 08:46:00.654: D/dalvikvm(381): Trying to load lib /data/data/com.fw.test/lib/libstlport_shared.so 0x41e407e8
11-12 08:46:00.669: D/AndroidmoduleModule(381): (main) [18,433] inside onAppCreate
11-12 08:46:00.669: D/dalvikvm(381): Trying to load lib /data/data/com.fw.test/lib/libAlibrary-jni.so 0x41e407e8
11-12 08:46:00.719: D/dalvikvm(381): Added shared lib /data/data/com.fw.test/lib/libstlport_shared.so 0x41e407e8
11-12 08:46:00.719: D/dalvikvm(381): No JNI_OnLoad found in /data/data/com.fw.test/lib/libstlport_shared.so 0x41e407e8, skipping init
11-12 08:46:00.719: D/dalvikvm(381): Trying to load lib /data/data/com.fw.test/lib/libkroll-v8.so 0x41e407e8
11-12 08:46:00.879: D/dalvikvm(381): Added shared lib /data/data/com.fw.test/lib/libkroll-v8.so 0x41e407e8
11-12 08:46:01.039: D/dalvikvm(381): Added shared lib /data/data/com.fw.test/lib/libAlibrary-jni.so 0x41e407e8
11-12 08:46:01.054: D/dalvikvm(381): No JNI_OnLoad found in /data/data/com.fw.test/lib/libgeniusscanlibrary-jni.so 0x41e407e8, skipping init
11-12 08:46:01.959: E/TiApplication(381): (KrollRuntimeThread) [345,345] Sending event: exception on thread: KrollRuntimeThread msg:java.lang.UnsatisfiedLinkError: Couldn't load com.tgl.androidmodule: findLibrary returned null; Titanium 3.1.3,2013/09/18 12:01,222f4d1
11-12 08:46:01.959: E/TiApplication(381): java.lang.UnsatisfiedLinkError: Couldn't load com.tgl.androidmodule: findLibrary returned null
11-12 08:46:01.959: E/TiApplication(381): at java.lang.Runtime.loadLibrary(Runtime.java:365)
11-12 08:46:01.959: E/TiApplication(381): at java.lang.System.loadLibrary(System.java:535)
11-12 08:46:01.959: E/TiApplication(381): at org.appcelerator.kroll.runtime.v8.V8Runtime.loadExternalModules(V8Runtime.java:114)
11-12 08:46:01.959: E/TiApplication(381): at org.appcelerator.kroll.runtime.v8.V8Runtime.initRuntime(V8Runtime.java:81)
11-12 08:46:01.959: E/TiApplication(381): at org.appcelerator.kroll.KrollRuntime.doInit(KrollRuntime.java:175)
11-12 08:46:01.959: E/TiApplication(381): at org.appcelerator.kroll.KrollRuntime$KrollRuntimeThread.run(KrollRuntime.java:109)
Any suggestion?
Actually, this issue had nothing to do with my C++ lib, it was a pure Titanium problem. I understood thanks to this Jira issue that I only needed to install gperf to solve this issue. No need to say the error message was misleading. Thanks to Chris Stratton for his help.

libs suddenly won't load in dynamic linker (NDK)

I've been developing an NDK app for quite some time and it's been working well. However, today the app randomly decided to not start anymore, after I compiled it after making some nominal change. It's caused by a cryptic problem with loading the app's main library. Here's some log output:
08-11 18:38:11.220 D/dalvikvm( 1237): Added shared lib /mnt/asec/com.audia.rta-1/lib/libqtandroid.so 0x40513bd8
08-11 18:38:11.220 D/dalvikvm( 1237): No JNI_OnLoad found in /mnt/asec/com.audia.rta-1/lib/libqtandroid.so 0x40513bd8, skipping init
08-11 18:38:11.220 D/dalvikvm( 1237): Trying to load lib /mnt/asec/com.audia.rta-1/lib/librta.so 0x40513bd8
08-11 18:38:11.260 D/AndroidRuntime( 1237): Shutting down VM
08-11 18:38:11.260 W/dalvikvm( 1237): threadid=1: thread exiting with uncaught exception (group=0x40015560)
08-11 18:38:11.260 E/AndroidRuntime( 1237): FATAL EXCEPTION: main
08-11 18:38:11.260 E/AndroidRuntime( 1237): java.lang.UnsatisfiedLinkError: Cannot load library: reloc_library[1311]: 67 cannot locate '_ZNSaIcEC1Ev'...
08-11 18:38:11.260 E/AndroidRuntime( 1237):
08-11 18:38:11.260 E/AndroidRuntime( 1237): at java.lang.Runtime.loadLibrary(Runtime.java:434)
08-11 18:38:11.260 E/AndroidRuntime( 1237): at java.lang.System.loadLibrary(System.java:554)
08-11 18:38:11.260 E/AndroidRuntime( 1237): at com.audia.rta.RTA.onCreate(RTA.java:139)
According to some Google results, _ZNSaIcEC1Ev is part of libstdc++. I've checked, and it gets linked in the build process, and g++ is being used for linking.
Oddly enough, reverting to an older apk of the app fixes the problem, but compiling an old revision and installing that doesn't fix the problem. Everything in my build system is checked into version control, and I've done several clean builds. All my builds were working today and then they just stopped working. I didn't upgrade or install anything; it happened while I was in the middle of testing new code. What happened?
Update: Building from a freshly checked out copy doesn't fix the problem.
Update 2: Is there any way I can track down the link to that symbol, maybe with objdump? Maybe this could provide some clues.
I ended up compiling everything with a fresh NDK install, and it worked. It's as if the old one was corrupted somehow, though I have no idea how.
It was also an upgrade from r5b to r6, so maybe it's related to the NDK version.

Categories

Resources