Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android NDK UnsatisfiedLinkError - a surprising reason

Update 8/7/2013: The problem is solved now, but the reason for the error was quite unexpected, all the usual suspects for such errors were eliminated on start, and I have learned something new. See my answer below.


I'm pretty desperate here. Have an Android app with a native library, from where I call a method. No problem on all the systems I tested, and the program was out in Google Play without any trouble reports, used by thousands of users. Now, apparently a new ROM - Android version 4.2.2 - for HTC One phone is out. Users claim that it's the official build, upgraded form the official channel. When they try to start my app, it crashes, and the stack trace says:

java.lang.UnsatisfiedLinkError: Native method not found...

and the method name of which I know is there and worked fine a moment ago on the same device when they had Android 4.1 installed. I test it under Android 4.2.2 in emulators (don't have this particular device) and there is no problem. Also, the users tried uninstalling and reinstalling the app with the same result. Even sending them a private build, without any ProGuard/Dexguard protections does not help.

What else can cause java.lang.UnsatisfiedLinkError on Android? Or should I assume that this HTC ROM is simply buggy??? Did anyone else have similar problems on HTC One with Android 4.2.2?

Edit 7/24/2013

In the comments below another developer suggests that the system could have troubles finding my native library. I experimented on Genymotion 4.2.2 emulator by removing the native library file from the setup completely. The error message is different in this situation, got:

W/System.err: Caused by: java.lang.UnsatisfiedLinkError: Couldn't load cld from loader dalvik.system.PathClassLoader[dexPath=/data/app/com.hyperionics.avar-2.apk,libra‌​ryPath=/data/app-lib/com.hyperionics.avar-2]: findLibrary returned null

While in the stack trace messages I got from HTC One users with Android 4.2.2 I see this error message:

Caused by: java.lang.UnsatisfiedLinkError: Native method not found: com.hyperionics.avar.CldWrapper.detectLangNative:(Ljava/lang/String;)[Ljava/lang‌​/String;

To me it appears that the system finds the libcld.so file as needed, but does not find the method it needs there. Why??? I know the method is there, exported as needed, and every other device and system, also these running Android 4.2.2, finds it. Only HTC One with 4.2.2 fails there...

Update 7/25/2013

Started a bounty for 50 rep. points, as I don't have HTC One and am stuck. Will accept an answer that either points a way to solving the problem - and the answering person will test my code mod. to show it works - or proves that this is really a bug in the recent Android 4.2.2 ROM for HTC One. The app in question is https://play.google.com/store/apps/details?id=com.hyperionics.avar

Update 7/31/2013

The last day of the bounty and still no answers, no suggestions... So far, all such error reports I get come from Europe, reported brand is "htc_europe" or "vodafone_fr". Maybe the error is localized to Europe (France + Germany) only... If there is anyone out there with HTC One and Android updated to 4.2.2, I would be interested if the error happens in other countries or with other providers.

Greg

like image 540
gregko Avatar asked Jul 23 '13 18:07

gregko


3 Answers

There was no satisfactory answer during the bounty period. I ordered the device and will have to debug what most likely is a system bug in the device ROM for Android 4.2.2 update...

Update 6/20/2014 Another reason for an occasional UnsatisfiedLinkError

It turns out that sometimes, when updating an app from Google Play, native libraries are not installed correctly. Maybe the installer runs out of space, or some other strange system bug kicks in. Please see also this SO question and answers.

Update 8/6/2013 - mystery solved!

My HTC One ordered from Google Play arrived, and... mystery solved! The same crash happened also on the original Android 4.2.2 from Google Play. The problem was my library name: cld, which produces a shared library named libcld.so. Apparently the system has another shared library with the same name, where the methods I expect are not present, of course... Probably some "plugin" loaded this other libcld.so into the process memory, and my own library was skipped. I renamed the native library and the program started working at once.

I was not aware of the possibility of such name clashes on different builds of Android... Did anyone reading this see a warning somewhere in NDK docs about it? I guess I'll prefix from now on all native libraries I create with my company name or something.

like image 79
gregko Avatar answered Nov 18 '22 04:11

gregko


You could try taking the method definition from your library, and rewriting it into one of your classes, giving the method a different name. This may be very tedious, but at least you can be certain that your program will be able to find the method...

like image 1
Flotolk Avatar answered Nov 18 '22 04:11

Flotolk


defaultConfig {
    ...
    ndk {
        abiFilters "armeabi-v7a", "x86", "armeabi", "mips"
    }
}
like image 1
Pratik Avatar answered Nov 18 '22 03:11

Pratik