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.
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
I'm developing an Android Library and I'd like to have this result for Proguard.
I want to keep all package names, which I'm using "-keeppackagenames" to achieve.
I want to keep all class names.
I want to keep method names and method argument names for all public methods.
Other than that, I'd like to obfuscate and shrink everything else, including but not limited to all of non-public methods and even the body of the public methods.
How can I achieve that result?
Thank you very much beforehand for your help!
R8 itself is distributes as a library which has been run through R8. For that library we want to achieve exactly what you ask to ensure that developers using the library will not by accident use any APIs which are not supposed to be public (this has nothing to do with protecting IP as the project is open source).
The rules can be found here and I will explain the rationale for them below.
We try to be indirect and use annotations, so the main rules are:
-keep #com.android.tools.r8.Keep class * { public *; }
-keep #com.android.tools.r8.KeepForSubclassing class * { public *; protected *; }
All API classes are then annotated with #Keep or #KeepForSubclassing.
Then a number of attrubutes are kept
-keepattributes SourceFile, LineNumberTable, InnerClasses, EnclosingMethod, Exceptions, Signature
SourceFile and LineNumberTable are kept to get retracable stack traces. The rest for javac compilation and IDE integration for library users.
Then
-keepparameternames
is there for IDE integration getting the names of arguments in the API, and
-keeppackagenames com.android.tools.r8
-repackageclasses com.android.tools.r8.internal
to move as many classes as possible into the internal name space so the renamed classes does not show up in IDE's.
There are a few additional rules in the file to handle cases not covered by the annotation based approach.
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 want to obfuscate a class and its public method. I am using following code to obfuscate :
-keep class !com.supermentor.ApiService { *; }
but this doesn't work. Does anyone has idea? How to obfuscate only one class and its public methods.
This worked for me:
-keep class !com.supermentor.ApiService,** { *; }
But be aware order is important, firs describe what you want to exclude and then what you want to keep. In this example, you want to obfuscate ApiService and you want to everything else.
As above.
My ProGuard config is
-keepclassmembers public class myApp.interfaces.**
-keepclasseswithmembernames public class myApp.interfaces.**
-keepattributes Signature
-keepparameternames
Really new to this and no real idea what I'm doing.
What I'm trying to achieve is to make Proguard not change the method and variable names of all Classes inside myApp.interfaces.*. If they want to rearrange some algo stuff to optimise it or whatever, it's fine. As long as the names are not changed.
This must be done because of the Serializable issue between server and client.
Simply use:
-keep class myApp.interfaces.** { *; }
It will not touch the class or its members. If you get errors / warnings, Rebuild the project.