Android app loading ARM shared library on x86 device fails - android

I have a really simple android app. I want to load a shared library called 'libcamera.so' and then call methods via JNI.
I do not own this library and I do not have access to the source code. It was originally compiled for ARM.
An x86 version is not available.
The project can detect the library and correctly shows it in the jniLibs folder.
Within my main activity I am trying to load the 3rd party library like so:
static {
System.loadLibrary("camera");
}
When this line executes, logcat shows the following:
02-06 14:11:38.517 4455-4455/uk.co.test.myApp E/art: dlopen("/data/app/uk.co.test.myApp-2/lib/x86/libcamera.so", RTLD_LAZY) failed: dlopen failed: "/data/app/uk.co.test.myApp-2/lib/x86/libcamera.so" has unexpected e_machine: 40
02-06 14:11:38.519 4455-4455/uk.co.test.myApp E/AndroidRuntime: FATAL EXCEPTION: main
Process: uk.co.test.myApp, PID: 4455
java.lang.UnsatisfiedLinkError: dlopen failed: "/data/app/uk.co.test.myApp-2/lib/x86/libcamera.so" has unexpected e_machine: 40
at java.lang.Runtime.loadLibrary(Runtime.java:371)
at java.lang.System.loadLibrary(System.java:988)
at uk.co.test.myApp.MainActivity.<clinit>(MainActivity.java:17)
at java.lang.reflect.Constructor.newInstance(Native Method)
at java.lang.Class.newInstance(Class.java:1603)
at android.app.Instrumentation.newActivity(Instrumentation.java:1066)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2226)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5258)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Other 3rd party apps which use this library can run on my x86 device (Epson BT350) so I feel like this should be possible.
I have become aware of something called 'Houdini' which allows ARM apps to run on x86 - I have checked and my device has this library so im confused why its not doing its job. But its also quite likely I dont really understand how Houdini works!
I have tried running on an x86 emulator - same error.
Any ideas would be greatly appreciated.

I solved the problem by forcing my app to only build an armeabi version. I did this by using an abifilter within gradle. I added the following to my defaultConfig
ndk {
abiFilters "armeabi"
}
This will then run on my x86 device because Houdini will kick in and do the translation. Its not ideal because this translation affects performance - but its a start and gets me to the next stage.

Related

Pjsip java.lang.UnsatisfiedLinkError: dlopen failed: for armeabi-v7a

I am trying to build libpjsua2.so using armeabi-v7a architecture type.
Here are the steps I followed:
https://trac.pjsip.org/repos/wiki/Getting-Started/Android
I just changed TARGET_ABI=armeabi-v7a ./configure-android --use-ndk-cflags and rest everything kept as it is.
It worked well with arm64-v8a and I am able to run project on Google Pixel.
When I build armeabi-v7a, I didn't receive any errors but when I run the project on Nexus 5, it gives me the following error:
08-09 16:52:01.625 19296-19296/com.pjdroid.sample E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.pjdroid.sample, PID: 19296
java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "__aeabi_memclr8" referenced by "/data/app/com.pjdroid.sample-1/lib/arm/libpjsua2.so"...
at java.lang.Runtime.loadLibrary(Runtime.java:372)
at java.lang.System.loadLibrary(System.java:1076)
at com.pjdroid.sample.MyApp.(MyApp.java:278)
at com.pjdroid.sample.MainActivity.onCreate(MainActivity.java:114)
at android.app.Activity.performCreate(Activity.java:6251)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
I tried several times make clean and remove everything but every time I received this error.
I think there's some issue in creating this file for armeabi-v7a.
Can you suggest me if I am doing anything wrong in this?
Read the documentation. This is what the PJSIP getting started guide has to say (almost at the bottom)
UnsatisfiedLinkError exception with "cannot locate 'rand'" message.
As described ​here, this happens if you've built your native components with the android-21 target, but are trying to run it on a device with an older Android version, so re-run configure with APP_PLATFORM set to lower platform version, e.g:
APP_PLATFORM=android-19 ./configure-android

TensorFlow + AndroidScanner - couldn't find "libopencv_java3.so"

I'm having a problem with combining Tensorflow and AndroidScanner.
I use Tensorflow to display an overlay over the camera feed. I take a picture with the camera, and then send it to a server. It works.
Now I imported the AndroidScannerDemo, I want to use the taken picture and crop/transform it with the newly imported module. It crashes. When I open the ScanActivity (from the AndroidScannerDemo), it tries to load opencv, and never succeeds. The error message is as follows:
FATAL EXCEPTION: main
Process: fr.pacifica.insurancechat.debug, PID: 2139
java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/fr.pacifica.insurancechat.debug-OI_d1EANbiczpZEwAHYdkw==/base.apk"],nativeLibraryDirectories=[/data/app/fr.pacifica.insurancechat.debug-OI_d1EANbiczpZEwAHYdkw==/lib/arm64, /data/app/fr.pacifica.insurancechat.debug-OI_d1EANbiczpZEwAHYdkw==/base.apk!/lib/arm64-v8a, /system/lib64, /system/vendor/lib64]]] couldn't find "libopencv_java3.so"
at java.lang.Runtime.loadLibrary0(Runtime.java:1011)
at java.lang.System.loadLibrary(System.java:1657)
at com.scanlibrary.ScanActivity.(ScanActivity.java:125)
at java.lang.Class.newInstance(Native Method)
at android.app.Instrumentation.newActivity(Instrumentation.java:1190)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2837)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3046)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1688)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6809)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
When I delete TensorFlow references from gradle/code, the imported module works just fine.
The project you imported, only builds 32-bit versions of libScanner.so, and therefore only uses the 32-bit versions of libopencv_java3.so. In the short run, you can keep that, only set
android {
defaultConfig {
ndk {
abiFilters 'armeabi-v7a'
}
}
}
This will cause your APK run in 32-bit mode on arm64 devices.
In the long run, you should update the Scanner library to build in 64-bit, too. This may have a significant performance gain.
from August 2019, 64-bit support is required for all apps in Play Store
I had the same problem with some mobiles (64 bits processor)
Here is the libs you need for every single arquitecture. You can download it and import manually.
https://github.com/jhansireddy/AndroidScannerDemo/tree/2cd23d3d362d0a6248cf489a79ebc4ba2c425c60/ScanDemoExample/scanlibrary/src/main/libs

Couldn't load alljoyn_java from loader dalvik.system

i am creating a chat application by using Alljoyn framework and am getting the following error can somebody please help me. The alljoyn jars are already set up!!!
FATAL EXCEPTION: main
Process: com.example.vikesh.chat_application, PID: 4326
java.lang.UnsatisfiedLinkError: Couldn't load alljoyn_java from loader dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.example.vikesh.chat_application-1.apk"],nativeLibraryDirectories=[/data/app-lib/com.example.vikesh.chat_application-1, /vendor/lib, /system/lib]]]: findLibrary returned null
at java.lang.Runtime.loadLibrary(Runtime.java:358)
at java.lang.System.loadLibrary(System.java:526)
at com.example.vikesh.chat_application.AlljoynService.<clinit>(AlljoynService.java:1252)
at java.lang.Class.newInstanceImpl(Native Method)
at java.lang.Class.newInstance(Class.java:1208)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:2553)
at android.app.ActivityThread.access$1800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
You need to put the AllJoyn liballjoyn_java.so file within your project.
For example, in Android Studio, the usual location for this file is:
[your_project_dir]/app/src/main/jniLibs/armeabi/
The armeabi portion of the above path is assuming that the AllJoyn .so file that you have previously built is targeted for the 'arm' CPU (the armeabi instruction set).
Note: When I deleted the .so file from my app, I got the same error that you are reporting. When I put the .so file back I still got the same error. I had to uninstall the app from my Android device, and in Android Studio I had to clean and rebuild the app, before I was able to get past this error.
Some other things to consider...
Make sure in your App that you are calling
static {
System.loadLibrary("alljoyn_java");
}
Make sure that the liballjoyn_java.so you previously built matches the cpu instruction set of your Android device. You can verify your Android's instruction set by using an app such as Droid Info, for example. Assuming that it is armeabi, then when you build the AllJoyn core project, you need to specify at a minimum the following switches in your scons build command....
scons BINDINGS="cpp,java,c" OS=android CPU=arm VARIANT=release
Finally, the following Stackoverflow link discusses general reasons the error you are seeing can occur:
java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader

UnsatisfiedLinkError in pjsip library

I build Pjsip library and use its sample in android studio .
question
When I run that i got this error.How could I solve it ? thanks in advance.
exception
jsip.pjsua2.app E/AndroidRuntime: FATAL EXCEPTION: main
Process: org.pjsip.pjsua2.app, PID: 4360
java.lang.UnsatisfiedLinkError: No implementation found for void org.pjsip.pjsua2.pjsua2JNI.swig_module_init() (tried Java_org_pjsip_pjsua2_pjsua2JNI_swig_1module_1init and Java_org_pjsip_pjsua2_pjsua2JNI_swig_1module_1init__)
at org.pjsip.pjsua2.pjsua2JNI.swig_module_init(Native Method)
at org.pjsip.pjsua2.pjsua2JNI.(pjsua2JNI.java:2351)
at org.pjsip.pjsua2.Endpoint.(Endpoint.java:68)
at org.pjsip.pjsua2.app.MyApp.(MyApp.java:296)
at org.pjsip.pjsua2.app.MainActivity.onCreate(MainActivity.java:92)
at android.app.Activity.performCreate(Activity.java:5990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2332)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2442)
at android.app.ActivityThread.access$800(ActivityThread.java:156)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1351)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:211)
at android.app.ActivityThread.main(ActivityThread.java:5389)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1020)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815)
It may happen for several reasons. First, check if you attached the native library correctly. For that create a folder named "jniLibs" into the projects
app/src/main/jniLibs
then put your armeabi architecture library like
armeabi/libpjsua2.so
for other architecture like armeabi-v7a use
armeabi-v7a/libpjsua2.so
like this.
there are other reasons may happen. If you build pjsip library for armeabi architecture only and running your application in an x86 architecture device then this error may occur. So check it also if you have built it for that application.
Please take a look at this thread: building pjsua2 dll
the important thing to know here is that the error you show in your question is caused by the fact that the pjsua2.dll (a c++ dll) is not in your output directory.

java.lang.UnsatisfiedLinkError after updating to Android 5.0

I'm developing an Android app which uses a native library called liballjoyn_java.so (available here in the Android Core SDK). I'm using Android Studio as IDE and Maven as build/dependency system (not Gradle). With Android KitKat everything worked like a charm and this is how I added the library to my project:
1) Added the library to my local Maven repo
mvn install:install-file -Dfile=./alljoyn/liballjoyn_java.so -DgroupId=org.alljoyn -DartifactId=liballjoyn_java -Dversion=14.06.00 -Dscope=runtime -Dpackaging=so
2) Defined a dependency in the POM file:
<dependency>
<groupId>org.alljoyn</groupId>
<artifactId>liballjoyn_java</artifactId>
<scope>runtime</scope>
<type>so</type>
<version>14.06.00</version>
</dependency>
3) Called it statically from my code:
static {
try {
System.loadLibrary("alljoyn_java");
Log.d("AllJoynManager", "static - Loaded AllJoyn native library");
} catch (Exception exception) {
Log.d("AllJoynManager", "static - Error loading AllJoyn native library");
exception.printStackTrace();
}
}
This was working perfectly under KitKat in my Nexus 4 phone but now I installed the official Android 5.0 OTA update and I get the following error on runtime:
11-28 17:57:39.988 30068-30068/com.avispalabs.kiihome E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.avispalabs.kiihome, PID: 30068
java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.avispalabs.kiihome-2/base.apk"],nativeLibraryDirectories=[/data/app/com.avispalabs.kiihome-2/lib/arm, /vendor/lib, /system/lib]]] couldn't find "liballjoyn_java.so"
at java.lang.Runtime.loadLibrary(Runtime.java:366)
at java.lang.System.loadLibrary(System.java:989)
at com.avispalabs.kiihome.helpers.network.alljoyn.AlljoynManager.<clinit>(AlljoynManager.java:38)
at com.avispalabs.kiihome.ui.activities.MainActivity.<init>(MainActivity.java:38)
at java.lang.reflect.Constructor.newInstance(Native Method)
at java.lang.Class.newInstance(Class.java:1572)
at android.app.Instrumentation.newActivity(Instrumentation.java:1065)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2199)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
11-28 17:57:55.432 30068-30068/com.avispalabs.kiihome I/Process﹕ Sending signal. PID: 30068 SIG: 9
I suspect the .so library might have been compiled in way which is somehow incompatible with the new Android 5.0 ART (?). The message that says it can't find the library is probably misleading (the exception is also seen when a library fails to load) but I'm not sure (another possibility is the .so is not correctly extracted or placed).
The library comes precompiled and is advertised to be compatible with JellyBean. I thought previous dynamic libraries would be compatible with new versions of Android, otherwise a lot of apps would break. If I install the same APK in a Nexus 4 with KitKat it just works.
Any advice is highly appreciated.
UPDATE: I have tested my project in a KitKat based device and switched the runtime to ART rather than Dalvik, and the project works fine. This problem seems to be tied to Android 5 rather than ART itself.
Answering my own question here. You can solve it by compiling liballjoyn_java as PIE as explained here:
https://jira.allseenalliance.org/browse/ASACORE-1208
This is a workaround until the AllJoyn guys publish a new Android build. Keep an eye here to get the updated release:
https://build.allseenalliance.org/ci/view/Core%20RB14.12%20SDK/job/branch-android-sdk/

Categories

Resources