Trouble with JNI integration in the build system

2,006 views
Skip to first unread message

Maxime Ripard

unread,
Jul 27, 2011, 7:51:05 AM7/27/11
to android-...@googlegroups.com
Hi,

I'm not quite sure what mailing list is the most appropriate for this
trouble. If I'm posting to the wrong one, sorry about that.

I'm trying to integrate an app to the build system, which uses JNI
bindings to the libusb.

I've put the libusb into the external folder, and it builds correctly.

My app is in package/apps, and the bindings are in the jni/ directory of
this app.

Everything builds fine, but when I try to call System.loadLibrary, I get
"java.lang.UnsatisfiedLinkError: Couldn't load ml: findLibrary returned
null" (libml being the bindings).

So, I've checked the content of the generated apk, and the lib is in it:

Archive: MissileControl.apk
Length Date Time Name
--------- ---------- ----- ----
918 2008-04-16 01:40 META-INF/MANIFEST.MF
960 2008-04-16 01:40 META-INF/CERT.SF
1714 2008-04-16 01:40 META-INF/CERT.RSA
1512 2008-04-16 01:40 AndroidManifest.xml
80992 2008-04-16 01:40 classes.dex
5328 2008-04-16 01:40 lib/armeabi/libml.so
821 2008-04-16 01:40 res/drawable-mdpi/arrows_down.png
757 2008-04-16 01:40 res/drawable-mdpi/arrows_left.png
800 2008-04-16 01:40 res/drawable-mdpi/arrows_right.png
762 2008-04-16 01:40 res/drawable-mdpi/arrows_up.png
2200 2008-04-16 01:40 res/drawable-mdpi/icon.png
3020 2008-04-16 01:40 res/layout-land/main.xml
2852 2008-04-16 01:40 res/layout/main.xml
1920 2008-04-16 01:40 resources.arsc
--------- -------
104556 14 files

So this part seems ok. Now, file tells me that :
lib/armeabi/libml.so: ELF 32-bit LSB shared object, ARM, version 1
(SYSV), dynamically linked, stripped

Which is ok too.

If I run strace on the process just before loadLibrary, here is the output :

access("/data/data/com.fe.android.ml/lib/libml.so", F_OK) = -1 ENOENT
(No such file or directory)
access("/vendor/lib/libml.so", F_OK) = -1 ENOENT (No such file or
directory)
access("/system/lib/libml.so", F_OK) = -1 ENOENT (No such file or
directory)
writev(3, [{"\5", 1}, {"dalvikvm\0", 9}, {"Exception
Ljava/lang/Unsatisfied"..., 109}], 3) = 119

And indeed, if I look into the /data/data/com.fe.android.ml/lib folder,
there is nothing in it. Which explains the loading problem, but raises
another one : Why the lib isn't copied at the apk installation ?

Reinstalling the apk doesn't seem to help. Do you have any idea on what
could be going on ?

Thanks,

--
Maxime Ripard, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

Magnus Bäck

unread,
Jul 27, 2011, 2:58:12 PM7/27/11
to android-...@googlegroups.com
On Wednesday, July 27, 2011 at 13:51 CEST,
Maxime Ripard <maxime...@free-electrons.com> wrote:

> I'm trying to integrate an app to the build system, which uses JNI
> bindings to the libusb.
>
> I've put the libusb into the external folder, and it builds correctly.
>
> My app is in package/apps, and the bindings are in the jni/ directory
> of this app.
>
> Everything builds fine, but when I try to call System.loadLibrary, I
> get "java.lang.UnsatisfiedLinkError: Couldn't load ml: findLibrary
> returned null" (libml being the bindings).

[...]

> If I run strace on the process just before loadLibrary, here is the
> output :
>
> access("/data/data/com.fe.android.ml/lib/libml.so", F_OK) = -1 ENOENT
> (No such file or directory)
> access("/vendor/lib/libml.so", F_OK) = -1 ENOENT (No such file or
> directory)
> access("/system/lib/libml.so", F_OK) = -1 ENOENT (No such file or
> directory)
> writev(3, [{"\5", 1}, {"dalvikvm\0", 9}, {"Exception
> Ljava/lang/Unsatisfied"..., 109}], 3) = 119
>
> And indeed, if I look into the /data/data/com.fe.android.ml/lib
> folder, there is nothing in it. Which explains the loading problem,
> but raises another one : Why the lib isn't copied at the apk
> installation ?

Are you by any chance installing the APK into /system/app? Applications
installed there are assumed to have their libraries installed to
/system/lib and therefore won't be subject to the usual shared library
extraction.

--
Magnus B�ck Opinions are my own and do not necessarily
SW Configuration Manager represent the ones of my employer, etc.
Sony Ericsson

Ying Wang

unread,
Jul 27, 2011, 4:44:13 PM7/27/11
to android-...@googlegroups.com
Magnus is right.
You should not use LOCAL_JNI_SHARED_LIBRARIES for a preloaded apk, use LOCAL_REQUIRED_MODULES instead.
In your app's Android.mk:
LOCAL_REQUIRED_MODULES := libml


--
Magnus Bäck                   Opinions are my own and do not necessarily

SW Configuration Manager      represent the ones of my employer, etc.
Sony Ericsson

--
You received this message because you are subscribed to the "Android Building" mailing list.
To post to this group, send email to android-...@googlegroups.com
To unsubscribe from this group, send email to
android-buildi...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-building?hl=en

Maxime Ripard

unread,
Jul 28, 2011, 5:33:46 AM7/28/11
to android-...@googlegroups.com
Thanks for your answers,
So, just to understand correctly.

Apps built in the build system are never installed in the system and
thus, libs in their apk are never copied to /data/data/<package>/lib.

I guess that it is the PackageManager that is responsible for this copy,
right ?

So, to ensure that the lib is present in the system, I need to use
LOCAL_REQUIRED_MODULES and add the module to PRODUCT_PACKAGES, right ?

But then, this lib won't be embedded in the apk, but will instead be in
/system/lib.

Is there anyway to have the lib embedded in the apk in my case ?

Maxime

On 27/07/2011 22:44, Ying Wang wrote:
> Magnus is right.
> You should not use LOCAL_JNI_SHARED_LIBRARIES for a preloaded apk, use
> LOCAL_REQUIRED_MODULES instead.
> In your app's Android.mk:
> LOCAL_REQUIRED_MODULES := libml
>

> On Wed, Jul 27, 2011 at 11:58 AM, Magnus B�ck

>> Magnus B�ck Opinions are my own and do not necessarily


>> SW Configuration Manager represent the ones of my employer, etc.
>> Sony Ericsson
>>
>> --
>> You received this message because you are subscribed to the "Android
>> Building" mailing list.
>> To post to this group, send email to android-...@googlegroups.com
>> To unsubscribe from this group, send email to
>> android-buildi...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/android-building?hl=en
>>
>

Ying Wang

unread,
Jul 29, 2011, 2:19:57 PM7/29/11
to android-...@googlegroups.com
On Thu, Jul 28, 2011 at 2:33 AM, Maxime Ripard <maxime...@free-electrons.com> wrote:
Thanks for your answers,
So, just to understand correctly.

Apps built in the build system are never installed in the system and
thus, libs in their apk are never copied to /data/data/<package>/lib.

I guess that it is the PackageManager that is responsible for this copy,
right ?

So, to ensure that the lib is present in the system, I need to use
LOCAL_REQUIRED_MODULES and add the module to PRODUCT_PACKAGES, right ?
LOCAL_REQUIRED_MODULES means: if the app is needed by the product (via PRODUCT_PACKAGES) then the library will be installed for that product as well.
If you put it in PRODUCT_PACKAGES there is no need to use LOCAL_REQUIRED_MODULES (though innocuous).
LOCAL_REQUIRED_MODULES is recommended because it defines the relationship between the 2 modules and you don't need to put extra module name to PRODUCT_PACKAGES.
 

But then, this lib won't be embedded in the apk, but will instead be in
/system/lib.

Is there anyway to have the lib embedded in the apk in my case ?
Sure you can still use LOCAL_JNI_SHARED_LIBRARIES to embed the lib in the apk, but it will not be used, unless the apk is installed separately later.
 

Maxime

On 27/07/2011 22:44, Ying Wang wrote:
> Magnus is right.
> You should not use LOCAL_JNI_SHARED_LIBRARIES for a preloaded apk, use
> LOCAL_REQUIRED_MODULES instead.
> In your app's Android.mk:
> LOCAL_REQUIRED_MODULES := libml
>
> On Wed, Jul 27, 2011 at 11:58 AM, Magnus Bäck
>> Magnus Bäck                   Opinions are my own and do not necessarily

>> SW Configuration Manager      represent the ones of my employer, etc.
>> Sony Ericsson
>>
>> --
>> You received this message because you are subscribed to the "Android
>> Building" mailing list.
>> To post to this group, send email to android-...@googlegroups.com
>> To unsubscribe from this group, send email to
>> android-buildi...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/android-building?hl=en
>>
>


Reply all
Reply to author
Forward
0 new messages