Enabling ProGuard causes failing signed APK generation? - android

I have enabled minifyEnabled in my gradle file for using the feature of ProGuard to obfuscates code as a result it throwing some error.
Note: there were 1 class casts of dynamically created class instances.
You might consider explicitly keeping the mentioned classes and/or
their implementations (using '-keep').
Warning: there were 309 unresolved references to classes or interfaces.
You may need to add missing library jars or update their versions.
If your code works fine without the missing classes, you can suppress
the warnings with '-dontwarn' options.
(http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedclass)
and much more.
I have gone through the ProGuard documentation.i guess this is what happening wrong.am using third party libraries and jars.and it confuses as i have more number of libraries and jars.how can i decide which one should keep in my proguard-rules.pro and which one doesn't ? And what else need to do for using ProGuard successfully and efficiently ?

ProGuard analyzes all the code in your application (that includes libraries) and generates warnings if it sees unresolved references (or other problems, but unresolved references is the important thing here). It is very common for libraries to refer to system or library code that doesn't exist in your project.
For example: Picasso optionally integrates with OkHttp, and has code referring to that library. But if you haven't included OkHttp ProGuard will warn about unresolved references.
A successful build must not have any warnings from ProGuard. ProGuard also checks for reflection, if there are unresolved references found in reflection, ProGuard will generate notes instead of warnings. Both warnings and notes may point to issues with the classpath. You could check the code yourself to see if there's an actual problem, or trust the libraries that their code works on Android (and on your target platform version).
Kevin Schultz opened up a public collection of ProGuard configuration files. His blogpost should help you get started with your configuration file.
http://www.kevinrschultz.com/blog/2014/02/15/proguard-with-gradle/
Do double check the configurations that you copy. They can be a little aggressive sometimes. If possible you want to avoid -dontwarn/dontnote {entire-package} and instead narrow down on the actual problems.

You need to add proguard rules specific to the libraries you use. A compilation of such rules is available at https://github.com/StarWar/android-proguard-snippets/tree/master/libraries
You can also try adding dontwarn directive for packages causing issues. An example of this would be -dontwarn org.codehaus.jackson.**

Related

How Do I Teach ProGuard to Get Rid of Something It Is Keeping That I Am Not Using?

I have an Android project with a proguard-rules.pro file for the app module that contains only the following:
# ProGuard rules
-dontobfuscate
-dontwarn android.arch.util.paging.CountedDataSource
-dontwarn android.arch.persistence.room.paging.LimitOffsetDataSource
I am not keeping anything myself. All -keep rules are coming from something else, whether that is the rules provided by getDefaultProguardFile('proguard-android-optimize.txt') or from rules packaged in libraries.
However, stuff is being kept that I am not using. If I use the Android Studio APK Analyzer on my release build, while lots of things are removed by ProGuard, lots of other things are kept that I am not referencing.
For example: through transitive dependencies, I have the Support Library module that contains ViewPager in the app's dependencies tree. However, I am not (presently) using ViewPager in this app. Despite this, something is causing it to be kept, as the APK Analyzer shows 107 defined methods for android.support.v4.view.ViewPager, including its constructor.
I could use various ProGuard options to track down why this is being kept. However, it is not coming from my rules. There is no -keep of my own that needs fixing — the -keep is coming from somebody else, presumably a Google engineer.
So, how do I get rid of ViewPager? Is there a way that I can override the -keep rule that is causing it to be kept (e.g., using allowshrinking)? If so, how does ProGuard, as invoked by Android Studio, determine whose -keep rule wins?
The ViewPager class isn't kept in a small app that I just checked, so it must be other code or other rules in your project indeed.
You can start with letting ProGuard print out the chain that triggers ViewPager to be kept:
-whyareyoukeeping class android.support.v4.view.ViewPager
You may need to repeat this a number of times for various classes and methods to get to the root cause. ProGuard doesn't print out which rule exactly is responsible -- admittedly, this would be a useful feature.
You can then look for the proguard.txt file in build/intermediates/exploded-aar that contains a matching rule.
As for a solution at that point:
It is not possible to override -keep rules; they only accumulate.
As far as I know, the Android Gradle plugin also doesn't support disabling overly conservative proguard.txt files in libraries, so you'd need to create a custom .aar file with the updated rule, or send a suggestion to the developers of the library.

Getting "unresolved references" and "can't find superclass" warnings from Proguard

I have integrated some third-party source into my android project and I'm having trouble getting it to build with proguard enabled. The build is failing with this:
Warning: there were 123 unresolved references to classes or interfaces.
You may need to add missing library jars or update their versions.
If your code works fine without the missing classes, you can suppress
the warnings with '-dontwarn' options.
(http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedclass)
Warning: there were 201 unresolved references to program class members.
Your input classes appear to be inconsistent.
You may need to recompile the code.
(http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedprogramclassmember)
Warning: Exception while processing task java.io.IOException: Please correct the above warnings first.
:app:transformClassesAndResourcesWithProguardForRelease FAILED
FAILURE: Build failed with an exception.
There are MANY notes and warnings to sort through and I can't make heads or tails of it. I have tried adding --keep class example.package.** { *; } for everything that seems to be causing warnings, but it is still failing. Can anyone suggest a strategy for dealing with issues like this? For example, if I see this:
Warning: info.guardianproject.netcipher.client.MyDefaultClientConnectionOperator: can't find superclass or interface ch.boye.httpclientandroidlib.impl.conn.DefaultClientConnectionOperator
what should I do about it?
Adding the following to your proguard-file will solve the compile problem:
-dontwarn info.guardianproject.netcipher.**
That said, you should read up on any ramifications that would come with this. Proguard is usually giving warnings for a good reason.
The reason you get those warnings is that guardianproject messed up with dependencies. As you can see here NetCipher does not have any dependencies. And httpclientandroidlib is clearly an outern project. Inside Netcipher they have built the .jar library and not packaging it into their library. Unfortunately, httpclientandroidlib is not available through jcenter dependency.
There are two solutions:
Proposed by #Tommie: add
-dontwarn info.guardianproject.netcipher.**
to you proguard-rules.pro file if those dependecies are not necessary. You just get rid of warning, sometimes it is a good way. But usually does not work. Then go to step two
You need to add httpclientandroidlib manually to your project.
Download a project from github as .zip
Add new module to your project, name it httpclientandroidlib (name is arbitrary. I name it like that just for reference)
Copy folder structure ch.boye.httpclientandroidlib to new module's src folder
Replace module's AndroidManifest with the one from httpclientandroidlib library.
Add dependecy to your main aa module:
compile project(':httpclientandroidlib')
Then you can start working with the project.

Gradle issue - You may need to add missing library jars or update their versions

When I try to generate a release version for my app I get the bellow error :
Error:Execution failed for task ':app:proguardRelease'.
java.io.IOException: Please correct the above warnings first.
Blockquote
You may need to add missing library jars or update their versions.
If your code works fine without the missing classes, you can suppress
the warnings with '-dontwarn' options.
(http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedclass)
How can I force Android Studio Gradle plugin to use -dontwarn option ?
This occurs because the release build is using Proguard. You will need to add Proguard rules in proguard-rules.pro for some of the dependencies you are using. Most libraries provide the Proguard rules needed; look on their README page.
The -dontwarn option isn't an option for Android Studio or the Android Gradle Plugin. It is a ProGuard option used to tell ProGuard not to warn you about potential problems.
From the ProGuard manual:
-dontwarn
Specifies not to warn about unresolved references and other important problems at all. The optional filter is a regular expression; ProGuard doesn't print warnings about classes with matching names. Ignoring warnings can be dangerous. For instance, if the unresolved classes or class members are indeed required for processing, the processed code will not function properly. Only use this option if you know what you're doing!
If you need to use this option, then it should go in your project-specific ProGuard file (see here if you don't know how to add your own ProGuard file).

Gradle release build with proguard: java.lang.IncompatibleClassChangeError and java.lang.NoSuchMethodError

I recently migrated a project from Eclipse/Ant to Android Studio/Gradle. I am able to successfully build a signed release version of the project with proguard enabled. However, while testing the release version, I'm getting crashes from certain library projects and jars (which work fine when building a debug version).
For example, when attempting to upload a file to Dropbox (a jar dependency), I get the following error:
java.lang.IncompatibleClassChangeError: interface not implemented
at com.dropbox.client2.session.AbstractSession.sign(SourceFile:238)
at com.dropbox.client2.DropboxAPI.putFileRequest(SourceFile:2199)
at com.dropbox.client2.DropboxAPI.putFileOverwriteRequest(SourceFile:1571)
at com.dropbox.client2.DropboxAPI.putFileOverwrite(SourceFile:1537)
Also, when attempting to sign into Box (a library project dependency), I get the following error:
java.lang.NoSuchMethodError: org.apache.http.conn.params.ConnManagerParams.setMaxTotalConnections
at com.box.restclientv2.BoxBasicRestClient.()
at com.box.boxjavalibv2.BoxRESTClient.()
at com.box.boxjavalibv2.BoxClient.createRestClient()
at com.box.boxjavalibv2.BoxClient.()
at com.box.boxandroidlibv2.BoxAndroidClient.(SourceFile:49)
at com.box.boxandroidlibv2.activities.OAuthActivity.startOAuth(SourceFile:71)
at com.box.boxandroidlibv2.activities.OAuthActivity.onCreate(SourceFile:52)
I have other jars and library projects that work just fine...
Again, there are no issues with either of these when building a gradle debug build (no proguard). I was also able to create a release build with proguard enabled using ant without any issues (able to sign into both Dropbox and Box).
Any ideas?
You appear to be including a version of the org.apache.http library. In principle, this library is already part of the Android runtime android.jar, so you shouldn't add it to your project. ProGuard is probably printing warnings about these duplicate classes.
In practice, it may be a newer version of the library, and some of your code may be using additional classes from this version. You then probably should leave the names of the classes, fields, and methods untouched, to avoid introducing (additional) conflicts:
-keep class org.apache.http.** { *; }
A build process may filter out the classes, or it may be adding the above line, but I don't think the default Android builds currently do either.
You need to -keep Proguard from removing or renaming all the class and method names that it can't determine are referenced from code that it doesn't processes, that are referenced via reflection (e.g. XML references), etc.
Keeping all apache classes may keep more than necessary (which is OK) but it may not be enough to fix all the Proguard issues.
It's good to ask why it worked from your ant build without this -keep. Maybe the ant build didn't actually call Proguard (ant is tricky), maybe it used a different Proguard data file, or maybe the relevant libraries changed in the meantime. You can debug that by listing hypotheses and testing them. E.g. if you put a malformed command in the Proguard data file then run the ant build, you can tell whether it actually runs Proguard or not.

Proguard errors when exporting Android project after updating to ADT 20

After updating to ADT 20 I can no longer successfully export any of my Android projects. I get:
Proguard returned with error code 1. See console
In the console I get tons of the can't find referenced class warnings and occasionally the can't find superclass or interface warning. At the end of the warnings I get something like this:
You should check if you need to specify additional program jars.
Warning: there were 199 unresolved references to classes or interfaces.
You may need to specify additional library jars (using '-libraryjars').
java.io.IOException: Please correct the above warnings first.
at proguard.Initializer.execute(Initializer.java:321)
at proguard.ProGuard.initialize(ProGuard.java:211)
at proguard.ProGuard.execute(ProGuard.java:86)
at proguard.ProGuard.main(ProGuard.java:492)
Each time I attempt to build I get different numbers of warnings (it's not very consistent). Also, when I perform a clean before export, the export completes without producing any warnings, but the resulting APK crashes on launch often due to ClassNotFoundException.
My proguard-project.txt includes the necessary -keep class rules for the Android Support Library and ActionBarSherlock.
I had no problems building this project before ADT 20. I even tried building my last release (which obviously built fine when I released it), but I get the same proguard warnings and failed export.
I've tried adding -libraryjars and/or -dontwarn rules as many other SO questions suggest, but to no avail. It will sometimes build successfully, but the APK created crashes on launch.
Any suggestions?
There is a bug in AAPT where it will only process
<fragment android:name"..." />
but not
<fragment class="..." />
We'll fix AAPT but in the meantime you can use the other attribute and it'll work.
In ADT 20, we use a feature of aapt (see the -G flag) which can create a proguard file which contains keep rules for exactly the custom views used by your code.
The old proguard config files would keep all views. When you used a library project such as the compatibility library, where you might be using only a small subset of the available code, this could end up including a lot of stuff you don't need. By removing the generic keep rules, and adding a new keep file based on your application, your .apks would get smaller since a lot of unused stuff can be removed.
One area where this can go wrong is if you update to Tools 20 (so you have the new smaller proguard-android.txt file), and you continue to use ADT 18. Make sure to use ADT 20, since it will add in not just the proguard files specified in your project.properties setting, but the generated proguard file listing the keep files from aapt -G as well. I believe the ant build will also use the -G feature.
(Note - see http://code.google.com/p/android/issues/detail?id=35107 for any followups on this)
Reportedly, there are problems with a recent update of the Eclipse plugin in the ADT, which doesn't properly recompile all source code. In that case, ProGuard will print out warnings about your program classes (as opposed to the library classes). You should check if the export (and the resulting application) works without ProGuard. You should also check if the Ant build works ("ant release"). That could then be a workaround.

Categories

Resources