Using proguard with dagger 1.2.2 - android

Is there any shortcut (I know, I know, I shouldn't be asking for a magic bullet) to getting dagger 1.2.2 to work with proguard?
We're having issues at the moment, and we know that we have to move over to Dagger 2.0 in order to get proguard working, from this question
Dagger + Proguard obfuscation, Errors creating object graph
However, ObjectGraph no longer exists in Dagger 2.0 so before we sit down and do a moderate sized refactor, I was just wondering if there was any ignore rule I could put in my proguard file in order to get this to compile in the super short term?
Thanks

You can use this Dagger Proguard Helper library that leverages Java Annotations processing.

For Dagger, you need to keep the generated classes:
-keep class **$$ModuleAdapter
-keep class **$$InjectAdapter
-keep class **$$StaticInjection
Unfortunately, you also need to preserve the corresponding base classes from your project:
-keep class com.example.SomeClass
That way, Dagger can still combine the corresponding pairs of classes. You can figure out the base classes by listing the generated classes in the gen directory of your project (e.g. com/examples/SomeClass$$ModuleAdapter.class).
Finally, you need to preserve one Dagger class:
-keep class dagger.Lazy

#-dontobfuscate
-keepnames class your.package.**
The big problem is that dagger 1.2.2 creates strings like "method/your.package.YourClass", which are not altered by -adaptclassstrings
This will let you run obfuscation along with your build, plus what other folks added about keeping classes in other answers.
You won't be obfuscating your class names, but fields and methods will. Better than nothing! Or you can disable obfuscation everywhere, just use shrinking.

Related

Proguard and com.google.android.gms.common.api.internal.BasePendingResult$ReleasableResultGuardian

play-services-base-16.0.1.aar (mvnrepository) has proguard.txt with following content:
# b/35135904 Ensure that proguard will not strip the mResultGuardian.
-keepclassmembers class com.google.android.gms.common.api.internal.BasePendingResult {
com.google.android.gms.common.api.internal.BasePendingResult$ReleasableResultGuardian mResultGuardian;
}
But you can see in classes.jar that type of mResultGuardian is already obfuscated to BasePendingResult.zaa. I guess that is why I get
Note: the configuration refers to the unknown class 'com.google.android.gms.common.api.internal.BasePendingResult$ReleasableResultGuardian'
How that's supposed to work? I'm new to Proguard and only have very basic understanding of what is going on so please make your answers simple :)
Project details:
gradlew version: 5.4
build plugin: com.android.tools.build:gradle:3.2.0
Unfortunatelly I can't update gradle build plugin to 3.3.* or 3.4.* right now because some of the scripts are incompatible and would require significant refactoring.
app/proguard.txt (from recommendations I've seen):
-keep class com.google.android.gms.analytics.** { *; }
-keep class com.google.android.gms.gcm.** { *; }
-dontwarn com.google.android.gms.**
But that doesn't help.
UPD
I end up upgrading to com.android.tools.build:gradle:3.4.1 (some api changes had to be adapted) which fixed the issue but I still don't get how that's supposed to work with rules like that.
“If the proguard set up in your project it does some jobs for us in the built process : Minification, obfuscation, repackaging and optimisation. Enabling it is straightforward if you’re using gradle, just set minifyEnabled to true for your release buildType in build.gradle and pass the default set of android optimisation rules.
This will help to shrink, speed up and protect your app. However it mainly works by removing code that is never called and renaming what’s left. This is all well and good until you encounter reflection.
Reflection lets you write code that can look up and execute other code based on its name (among other things)”
“You can also use ProGuard if you or any of the libraries in your app use reflection, here you specify rules as to which classes, methods and other parts of your app ProGuard should leave alone. You can list all these rules in a file and pass them to ProGuard via the proguardFiles method back in your build.gradle. The general convention is for this file to be called proguard-rules.pro”
These doc1, doc2 provide you more information on how to work with rules

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.

Proguard: Keep classes in a certain package

I have some classes which are used via reflection. It appears ProGuard is removing these when I build for release.
Is there any way to specify that all the classes in a particular package (as opposed to the specific class names) to not be removed when ProGuard runs. As a note, obfuscation is wanted. As another note, all these classes extend a single class which is present.
Thanks
Using -keep class com.yourpackage.name.** { *; } works well in my case. It essentially uses the wildcard to keep all classes belonging to that package. Also note the *; is required.
Also, to help debug your issue, you should check the generated seeds.txt, if the class is included then its kept.
Moreover it could be another issue like using public static inner classes or so. The best way to debug would be to decompile the minified apk using dex2jar and JD-GUI and manually skim through the code to see what's being stripped or kept. Don't forget to -dontdeobfuscate before.
Have you tried to add this line in your proguard-rules.pro file?
-keep class com.company.application.PackagePrefix*
{
*;
}
If you don't want to use package prefix you can use ** instead.
Hope it helps.

Conflict between Android data binding and Guava causes ProGuard error

I get the following error while compiling my Android app with ProGuard enabled.
Warning: library class android.databinding.tool.util.SourceCodeEscapers$1
extends or implements program class com.google.common.escape.CharEscaper
Warning: library class android.databinding.tool.util.SourceCodeEscapers$JavaCharEscaper
extends or implements program class com.google.common.escape.ArrayBasedCharEscaper
Warning: library class android.databinding.tool.util.SourceCodeEscapers$JavaCharEscaperWithOctal
extends or implements program class com.google.common.escape.ArrayBasedCharEscaper
Warning: there were 3 instances of library classes depending on program classes.
You must avoid such dependencies, since the program classes will
be processed, while the library classes will remain unchanged.
(http://proguard.sourceforge.net/manual/troubleshooting.html#dependency)
It appears that this is caused by a conflict between Android data binding and Guava. My app depends on Guava (com.google.guava:guava:18.0) and has data binding enabled. It appears that data binding has some sort of internal dependency on Guava and that is causing a problem with ProGuard.
I am running the latest beta version of gradle (2.0.0-beta5) so perhaps the problem is related to that.
So I was able to Build by adding this to proguard:
-dontwarn android.databinding.**
-keep class android.databinding.** { *; }
Which I don't think is entirely the right solution to just ignore those classes but I think we might just have to wait for an update from Google. After adding that to proguard I was able to build a release apk but it was crashing, I thought it was still proguard but found other errors in my code.

Android ProGuard obfuscation of library: keep class not working

Intro: I have in AS 1 project with 2 models:
Android library project with some "Public API class"
Android APP dependent on above library (the library module is on the dependency list)
Task: I want to obfuscate my library project because I want to expose it as public SDK but keep my code protected...
What I did: So I made custom ProGuard rules:
-dontshrink
-dontoptimize
-dontpreverify
-keep class com.org.my_public_api_class_name
I skip all other stages in order to eliminate where the bug is to only obfuscation stage.
Result: Build of the APP module fails with errors like
Error: cannot find symbol class my_public_api_class_name
It seems for me that the problem is that the obfuscation NOT skipped the class I wanted to, so now he has some meaningless name and therefore in the APP, where I'm using him, The original name not exist.
Thanks,
To exclude your class from obfuscation, try this:
-keep class com.org.my_public_api_class_name**
-keepclassmembers class com.org.my_public_api_class_name** {*;}

Categories

Resources