Michiyo Michiyo - 1 year ago 64
Java Question

Proguard: `NoSuchFieldError` despite field being in `seeds.txt`

I'm trying to apply proguard to an android app that uses a JNI library.

When the app runs, I'm getting this crash:

Thread[24,tid=8563,WaitingForJniOnLoad,Thread*=0xb510a400,peer=0x12f57190,"Service Thread"] recursive attempt to load library "/data/app/com.my.package-1/lib/arm/nativeLibrary.so"
No pending exception expected: java.lang.NoSuchFieldError: no "I" field "mNativeInstanceId" in class "Lcom/library/package/NativeDetector;" or its superclasses
at java.lang.String java.lang.Runtime.nativeLoad(java.lang.String, java.lang.ClassLoader, java.lang.String) (Runtime.java:-2)
at java.lang.String java.lang.Runtime.doLoad(java.lang.String, java.lang.ClassLoader) (Runtime.java:428)
at void java.lang.Runtime.loadLibrary(java.lang.String, java.lang.ClassLoader) (Runtime.java:369)
at void java.lang.System.loadLibrary(java.lang.String) (System.java:989)
at void com.library.package.NativeDetector.<clinit>() (SourceFile:48)
at com.library.package.DectorTypeA com.library.package.Detectors.createInstance() (SourceFile:63)
at com.library.package.DectorTypeA com.library.package.imageAnalysis.DetectorProvider.a() (SourceFile:31)
at com.library.package.DectorTypeA com.library.package.imageAnalysis.DetectorProvider.provideDetector() (SourceFile:24)
at com.library.package.DectorTypeA com.library.package.myService.e() (SourceFile:205)
at com.library.package.DectorTypeA com.library.package.myService.c(com.library.package.myService) (SourceFile:43)
at void com.library.package.myService$2.run() (SourceFile:226)

The error message looks like
has been obfuscated. However, the library module's
has this line:

com.library.package.NativeDetector: int mNativeInstanceId

meaning it was not obfuscated.

How do I fix this crash?

for the library module:

-renamesourcefileattribute SourceFile
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod,LocalVariableTable

-keep public class * {
public protected *;

-keepclassmembernames class * {
java.lang.Class class$(java.lang.String);
java.lang.Class class$(java.lang.String, boolean);

-keepclasseswithmembernames,includedescriptorclasses class * {
native <methods>;

-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);

-keep class com.library.package.NativeDetector

-keepclassmembers class com.library.package.NativeDetector {
private <fields>;


class NativeDetector {

private int mNativeInstanceId; //intialized in JNI code

Edit: I've also tried a proguard file with lines like this with no change in outcome:

-keep class com.om.library.package.NativeDetector {
private <fields>;

Answer Source

This configuration option seems wrong:

-keepclassmembers com.library.package.NativeDetector {
    private <fields>;

It should rather be

-keepclassmembers class com.library.package.NativeDetector {
    private <fields>;

but you can also merge this together with the already existing rule:

-keep class com.library.package.NativeDetector {
    private <fields>;


The problem you are facing might be because you added the proguard rules only to the library module. These are not automatically picked up for the application unless you specify them as consumerProguardFiles.