31

I have an application that uses an externally referenced library (that is, the directory of the library is in the same level as the application - it is not copied inside the application's folder). The library is referenced by the application and both the library and the application include proguard files. Everything works fine until I build the application. When I built the app, all referenced to the classes defined in the library are not found - I get 'cannot find symbol class ...) errors on all imports of library classes. As I found, this is because when rebuilding the application, proguard obfuscates all classes and variables and therefore the application cannot reference them. I have added the following to my build.gradle file,

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
    }
    debug {
        minifyEnabled false
    }
}

but it seems like when building the application, the above is not taken into consideration (or the building is done in release mode). If I change the above to the following (i.e., disable proguard in release mode),

buildTypes {
    release {
        **minifyEnabled false**
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
    }
    debug {
        minifyEnabled false
    }
}

the application compiles fine.

Is there a solution to this? Can I only enable proguard when creating a signed application?

Here is the library proguard file:

-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

-optimizations !method/marking/static

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService

-keepclasseswithmembernames class * {
    native <methods>;
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers class * extends android.app.Activity {
   public void *(android.view.View);
}

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

-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}

-dontwarn **CompatHoneycomb
-keep class android.support.v4.** { *; }

-keep class * extends java.util.ListResourceBundle {
    protected Object[][] getContents();
}

-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
    public static final *** NULL;
}

-keepnames @com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class * {
    @com.google.android.gms.common.annotation.KeepName *;
}

-keepnames class * implements android.os.Parcelable {
    public static final ** CREATOR;
}

-keep class com.google.android.gms.** { *; }

-keep public class com.google.ads.** { public *; }
-keep public class com.google.gson.** { public protected *; }
-keep public class com.google.ads.internal.** {*;} 
-keep public class com.google.ads.internal.AdWebView.** {*;} 
-keep public class com.google.ads.internal.state.AdState {*;} 
-keep public class com.google.ads.mediation.** { public *; }

-keep public class com.google.ads.searchads.** {*;} 
-keep public class com.google.ads.util.** {*;} 

-keep class com.google.ads.**
-dontwarn com.google.ads.**

-keepattributes *Annotation*

Is it a problem that I am using proguard in both the library and the application?

a.p.
  • 3,248
  • 7
  • 30
  • 48

2 Answers2

61

After some searching I found the answer. If you are using external/separate source libraries with your main project/application, you should not use a proguard on the library modules. Instead, you replace the following,

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
    }
    debug {
        minifyEnabled false
    }
}

with the following (in the build.gradle of the library/libraries):

buildTypes {
    release {
        consumerProguardFiles 'proguard-project.txt'
    }
}

where proguard-project.txt is the file that contains the proguard rules for your library project. When building the application (either in debug or release mode), the compiler will take care of all the rules (in the library and in the application).

a.p.
  • 3,248
  • 7
  • 30
  • 48
  • 3
    OMG I have the same situation and I lost a full week deep searching a solution. I felt so lost. Until now. Thank you so much! Thank you!! – Simon Nov 14 '15 at 02:05
  • Interesting - I imported a project from eclipse and it brought in all of its library projects, but it completely failed to edit the build.gradle files to specify consumerProguardFiles. – Carl May 18 '16 at 13:29
  • Adding this -- consumerProguardFiles 'proguard-project.txt' -- in my experimental plugin gets me a "Gradle sync failed: No signature of method: org.gradle.model.ModelMap.consumerProguardFiles() is applicable for argument types: (java.lang.String) values: [proguard-project.txt]". Do you have any idea of why it is complaining? thank you – Loebre Jul 07 '16 at 09:50
  • 1
    you deserve medal – Jemshit Nov 22 '16 at 15:57
  • Isn't minifyEnabled false by default? If yes, you're consumerProguardFiles won't work. – AppiDevo Mar 12 '17 at 20:55
  • 2
    As per doc it should be specified as: `android { defaultConfig { consumerProguardFiles 'lib-proguard-rules.txt' } ... } ` https://developer.android.com/studio/projects/android-library.html#Considerations – garnet Jun 06 '17 at 12:35
1

I think you need define proguard-rules for your libraries. Usually they are in the library docs.

(For example have a look at my answer here for ButterKnife lib: link)

Community
  • 1
  • 1
Andrew
  • 36,676
  • 11
  • 141
  • 113
  • 1
    The reason I have this problem is because I have defined proguard rules for my library. When I set minify to false (in both debug and release modes) the application compiles fine. – a.p. Jun 15 '15 at 14:30
  • So, you know where problem is. And it's not clear that you defined proguard rules, cos you didn't show that file. – Andrew Jun 15 '15 at 16:10
  • 1
    I have edited my question and added the proguard rules I am using. And yes, I know where the problem is, but the solution, i.e., disabling proguard is not a good solution. – a.p. Jun 16 '15 at 15:31