UnsatisfiedLinkError after running Proguard on project using JNI

5,108 views
Skip to first unread message

GJTorikian

unread,
Nov 13, 2010, 6:26:21 PM11/13/10
to android-ndk
After running a Proguard optimization/obfuscation process on my
project, I'm getting an UnsatisfiedLinkError on this line:

static {
System.loadLibrary("myjnilib");
}

Note that this is not an error with calling Java methods from my
native code; to account for that, I have aded this to my Proguard
config file:

-keepclasseswithmembernames class * {
native <methods>;
}

The problem here is that I don't know how to "preserve" my JNI lib, so
that the Android Java code can load the library. Proguard's
documentation doesn't provide much help on adding external libraries
(other than jars, with the -libraryjars option). Has anyone solved
this?

Olivier Guilyardi

unread,
Nov 13, 2010, 7:08:07 PM11/13/10
to andro...@googlegroups.com
Hi,

it is likely that some of your native methods are removed during Proguard shrink
phase, because they aren't called by the Java code. Check out Proguard's output
in project/obf/usage.txt.

You may either remove these methods if they aren't actually needed. Or tell
Proguard to preserve them no matter what, by using -keepclasseswithmembers
(instead of -keepclasseswithmembernames).

Eg:

-keepclasseswithmembers class * {
native <methods>;
}

Olivier

GJTorikian

unread,
Dec 5, 2010, 7:11:45 PM12/5/10
to android-ndk
Hi Oliver,

Thanks for the suggestion. Unfortunately, the error persists. I am not
even getting to the point where the methods are being called. The app
simply crashes when trying to load the JNI library.

On Nov 13, 4:08 pm, Olivier Guilyardi <l...@samalyse.com> wrote:
> Hi,
>
> it is likely that some of your native methods are removed duringProguardshrink
> phase, because they aren't called by the Java code. Check outProguard'soutput
> in project/obf/usage.txt.
>
> You may either remove these methods if they aren't actually needed. Or tellProguardto preserve them no matter what, by using -keepclasseswithmembers
> (instead of -keepclasseswithmembernames).
>
> Eg:
>
> -keepclasseswithmembers class * {
>     native <methods>;
>
> }
>
> Olivier
>
> On 11/14/2010 12:26 AM, GJTorikian wrote:
>
>
>
>
>
>
>
> > After running aProguardoptimization/obfuscation process on my
> > project, I'm getting an UnsatisfiedLinkError on this line:
>
> >    static {
> >            System.loadLibrary("myjnilib");
> >    }
>
> > Note that this is not an error with calling Java methods from my
> > native code; to account for that, I have aded this to myProguard
> > config file:
>
> > -keepclasseswithmembernames class * {
> >     native <methods>;
> > }
>
> > The problem here is that I don't know how to "preserve" my JNI lib, so
> > that the Android Java code can load the library.Proguard's

David Turner

unread,
Dec 6, 2010, 5:47:35 AM12/6/10
to andro...@googlegroups.com
Proguard shouldn't affect JNI libraries. Try to do an "unzip -l <your.apk>" and see if it has a file named "lib/armeabi/libmyjnilib.so"
If not, it's a packaging problem, and you should tell us exactly how you're generating your machine code and the final package that embeds it.


--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To post to this group, send email to andro...@googlegroups.com.
To unsubscribe from this group, send email to android-ndk...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/android-ndk?hl=en.


Olivier Guilyardi

unread,
Dec 6, 2010, 6:11:07 AM12/6/10
to andro...@googlegroups.com
On 12/06/2010 11:47 AM, David Turner wrote:

> On Sun, Nov 14, 2010 at 12:26 AM, GJTorikian <gjtor...@gmail.com
> <mailto:gjtor...@gmail.com>> wrote:
>
> -keepclasseswithmembernames class * {
> native <methods>;
> }

Great chances are that some of your native declarations are removed during the
shrinking phase, because not called by Java code.

Use this instead:

-keepclasseswithmembers class * {
native <methods>;
}

Ref: http://proguard.sourceforge.net/manual/usage.html#keepoptions

--
Olivier

Olivier Guilyardi

unread,
Dec 6, 2010, 9:47:03 AM12/6/10
to andro...@googlegroups.com
Oups, sorry, I missed this post (and repeated myself).

It sounds like your problem happens in JNI_OnLoad(). Do you define it?
If yes, what do you do in there?

Olivier

GJTorikian

unread,
Dec 12, 2010, 1:03:43 PM12/12/10
to android-ndk
David: after running that command I get a list of my META-INF files,
assets & res directories, classes.dex, e.t.c.---but no lib folder !

This is being packaged through a manual ant build. My *.so files are
located in a libs directory, which I define in build.xml :

<property name="external.libs.dir" value="libs" />
<property name="external.libs.absolute.dir" location="$
{external.libs.dir}" />

Standard stuff. But this led me to a separate part of my code: my
macrodef -dex-helper has this line:

<fileset dir="${external.libs.absolute.dir}" includes="*.jar" />

I assumed that changing it to

<fileset dir="${external.libs.absolute.dir}" includes="*.jar, **.so" /
>

would fix the problem, but no go. There are several places where *.jar
is defined and including **.so doesn't make a difference. I'll
continue to investigate as the problem is very much likely in this
packaging.

GJTorikian

unread,
Dec 12, 2010, 2:24:21 PM12/12/10
to android-ndk
Frustratingly enough, exporting the project via Eclipse & the new
Proguard integration DOES include the proper lib files. So I guess the
general question is how to copy my .so libs into the .apk via an ant
task.
Reply all
Reply to author
Forward
0 new messages