As title says: How do I get Proguard to keepclassmembers of entire package? Also to net delete methods with void signatures.
To keep all class members (fields and methods) of all classes in a given package and all of its subpackages:
-keepclassmembers class mypackage.** { *; }
This includes void methods. To only keep all void methods:
-keepclassmembers class mypackage.** { void *(...); }
These are unusual settings though, because keeping all class members or all void methods (without even keeping all classes) seems like a very random requirement.
For most configurations, -keep is more appropriate than -keepclassmembers, relevant classes are typically only public ones (matching public class), relevant classes typically extend a specific class or interface (e.g. matching extends somepackage.SomeClass), and relevant class members are typically a very specific set of public methods (e.g. public setters, matching public void set*(***)).
Related
I have some dagger classes in an android SDK that need to be protected from minification and obfuscation when creating and publishing the release version. I protect those by using custom proguard rules around the #Module and #DaggerGenerated annotations.
-keep #dagger.Module public class * { public <methods>; }
-keep #dagger.internal.DaggerGenerated public class * {public <methods>;}
Some of those classes have companion objects that should also be protected. At the moment, I protect them by annotating the companions specifically with #Keep. Is there a way to specify a proguard rule to automatically keep the companion?
I tried a few variations such as the one below but none of them got the job done.
-keep #dagger.Module class *$Companion { *; }
Perhaps not an ideal solution, but you could instead try to keep an entire package instead of individual files, using something like:
-keep class com.foo.bar.** { *; }
this way, you'll be covering any companion objects found here as well
When I run the usb debugging app, it saves the data correctly when I register the user:
But when I generate the signed apk, doing the same process saves it this way in Firebase Database:
What is happening? (i use android studio)
It's because proguard removes (obfuscation) unused code and renames classes and class members' (variables and methods) names to shorter names. There are two ways to keep them as you want
OPTION 1. Add annotation before every field and between parentheses put what name you want to be displayed in Firebase.
Method A) Add annotation to public fields
public class Datum {
#PropertyName("name")
public String name;
}
Methods B) Add annotation to public setter/getters if your fields are private
public class Datum {
private String name;
#PropertyName("name")
public String getName() {
return name;
}
#PropertyName("name")
public void setName(String name) {
this.name = name;
}
}
OPTION 2. Configure proguard file to keep class, field and method names as is.
Method A) Do it as per Firebase docs. Add following lines to your proguard file. Below lines mean names of every class member (field, constructor and method) in models package and in sub-package of models direcotry will be kept as-is.
# Add this global rule
-keepattributes Signature
# This rule will properly ProGuard all the model classes in
# the package com.yourcompany.models. Modify to fit the structure
# of your app.
-keepclassmembers class com.yourcompany.models.** { *;}
Method B) Adding classes one-by-one
If you want to keep name and class members of User class then add this.
-keep class com.josiah.app.data.models.User{ *;}
Methods C) Add all classes in a package
Let's say all of your model classes are inside models package and you want to keep names of all classes and class members intact in that package. Then you have to add following line into your proguard file.
-keep class com.josiah.app.data.models.** { *;}
NOTE:
* means everything inside class (fieds, methods and contructors)
** after package means everything in this package (subpackages and classes)
I want to know what does mean by
-ignorewarnings
-keep class * {
public private *;
}
-keep class * {
public private protected *;
}
And what if there are some model classes there in my code have some primitive types and getter setters. I don't want to obfuscate there names specially "keys" what rule I should use for them?
ProGuard also optimizes the bytecode, removes unused code
instructions, and obfuscates the remaining classes, fields, and
methods with short names.
-keep public class packageName.ParticularClassName.** { *; }
#Keep annotation to the code you want to keep. Adding #Keep on a class
keeps the entire class as-is. Adding it on a method or field will keep
the method/field (and it's name) as well as the class name intact.
Read Customize which code to keep.
I am trying to prevent proguard from obfuscating interface (or abstract class) methods parameters.
Lets say I have this interface in my lib :
package com.mypackage;
public interface MyLibListener {
void onSomething(boolean success, String message);
}
And this proguard file :
-keepparameternames
-keep interface com.mypackage.MyLibListener {
*;
}
Then I assemble release and I get :
package com.mypackage;
public interface MyLibListener {
void onSomething(boolean var1, String var2);
}
Same thing with abstract classes or using #Keep annotations. Obfuscation option keepparameternames seems to work only for regular classes. Any idea? Thanks!
(related SO : How to not obfuscate interface methods & it's parameters using Progaurd in android? and Proguard keep interface method variable names)
Add following ProGuard options to your configuration.
-keepattributes MethodParameters
If your class file hava method parameters metadata (compiled using Java8 -parameters or etc...)`, ProGuard will keep the metadata.
To keep all interface methods:
-keep interface * {
<methods>;
}
To keep all public and protected methods, which could be used by reflection:
-keepclassmembernames class * {
public protected <methods>;
}
While I don't understand, why one would want to keep abstract classes, which cannot be instanced anyway, therefore it's pointless to keep & know their names. In theory, one could exclude all that is not abstract with rules which start with -keep !abstract, but that's kind of redundant.
Your proguard file may lack some -keepattributes, especially a -keepattributes Signature.
Check this example proguard configuration for a library from the proguard documentation to look for ideas.
I would like proguard to obfuscate classnames. I have this line in Proguard.cfg
-keepclasseswithmembers class * {
public static <fields>;
}
-keepnames class * implements java.io.Serializable
-keep public class com.google.**
And I notice that what is not obfuscated is the class names. So running jdgui i see
com/test/abcd/ActualClass.java
public class ActualClassName extends Activity etc
moreover I see methods returning real classnames. like
ActualClassname aa();
and imports statements like
import com.abcd.ActualClassName
How do I get Proguard to obfuscate the classname itself. Its not just for Activities that I see this my Adapters are not being obfuscated. Well there is obfuscation going on but not class names.
Is the rules above what prevents the class names from being obfuscated?
Update: i have since removed the rules above and a Utility class that does not extend anything from Android is not being obfuscated. I'm now wondering if there is some implicit rule about keeping class names of classes that are referenced from classes that are being kept like Activity derivied classes? The classes whose names are not being obfuscated have a few things in common:
1) Static methods
2) Import of other types which are kept like those deriving from activity or serializable.
3) They have methods with parameters of other classes (Some of which might need to be kept).
However there is no where that I am specifically requesting that these utility classes should be kept.
There are several class that appear in your code that must retain the same fully qualified class name in order for android to be able to find them. One example as above are all Activity classes, as they are defined in the manifest by their full name as a String. If proguard were to rename the class then Android would no longer be able to find them.
The typical Proguard config will refer to the Proguard config in the Android SDK which will include several important lines like this one:
-keep public class * extends android.app.Activity
I think your problem is coming from your first line: '-keepclasseswithmembers' includes the class name, so in your case any class with a static field will keep its name. Changing it to simply '-keepclassmembers' will obfuscate the class names while leaving the static fields intact(which I'm assuming you want to do).
That said, I'm not sure why you want to do this, though. If you're trying to preserve the static variable names, shouldn't you want to preserve the class names as well, seeing as how that's how you'll be accessing the static fields? Why are you trying to preserve all of your static variable names?