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.
Related
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
Just wondering what exactly this means.
-keep class !com.my.package.** { *; }
Does it mean not obfuscate anything. Does it defeat the purpose of using proguard?
It will obfuscate your package classes including sub-packages and classes in them.
Why not if the app doesn't use any external library :)
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.
I'm using ProGuard for the first time. I have all my activities, fragments, list fragments, and the like inside the root package of my project (I tried to move them but made no difference). I'm using the standard proguard-android.txt plus the proguard-project.txt where I can put anything I want, it makes no difference to these classes, because they are just ignored.
They're not listed in usage.txt,seeds.txt, mapping.txt or dump.txt, and they're not in the dex (library classes seem to be correctly treated though).
I tried with -keep public class <my.project.rootpackage>.MyActivity one for every ignored class, and many other things, the last one is:
-dontshrink
-dontoptimize
-dontobfuscate
-keep public class * extends android.app.Application
-keep public class * extends android.support.v4.app.FragmentActivity
-keep public class * extends android.support.v4.app.Fragment
-keep public class * extends android.support.v4.app.ListFragment
-keep public class * extends android.preference.PreferenceActivity
I could be using a simpler project while learning, but I don't see why it shouldn't work, after all ProGuard seems to handle well the libraries. Of course, the project works well when built in debug mode.
ProGuard updated to v4.8, Eclipse 3.7.2, ADT and SDK updated, project target API 15, no messages from ProGuard.
What am I missing? I admit I've never had clear the build process. Do I have to learn Ant?
EDIT: when it doesn't work (that is, ProGuard finishes with an error), I often get this kind of errors:
Warning: my.project.package.ClassA: can't find referenced class my.project.package.ClassB
Note that the two classes can also be in the same package.
So it seems that the ignored classes are due to the fact that the "Build Automatically" feature prevented ProGuard from doing its job. With that unchecked, the "export signed application package" procedure goes well, but ProGuard is not obfuscating/shrinking. But this makes for another question.
References: Why start using -libraryjars when I never needed it before?
...EDIT: actually it's just the apk in project's bin that is not shrinked. The exported APK is fine. What an odyssey.
I have developed one android application which is having set of activities,background service and some other utility packages(which are written on pure java), i don't want to obfuscate activities and background service but need to obfuscate utility packages(pure java code), is it possible to do so?if yes then how to enable it in my proguard.cfg file?
OR in more precise way:
Application is using some external jars which are added to project's lib folder, I want only these jars should get obfuscated and rest of application code(activities , service etc...) should not get obfuscated. How to achieve the same using eclipse and proguard.cfg?
Regards,
Piks
If proguard is activated then Android will automatically include the used library files when creating a signed APK in Eclipse, so you don't have to specify this.
If the package name of your application is different from the package names of your libraries then you can simply use a wildcard and add this to your proguard.cfg file
-keepnames class com.mypackagename.** {
*;
}
If the packagename is the same, then you'll have to specify which classes should be obfuscated by hand, e.g.
-keepnames class com.mypackagename.MyApp {
*;
}
-keepnames class com.mypackagename.subpackage.MyClass {
*;
}