In order to configure proguard to keep all classes from a single package, say org.myorg.special, the following notation works:
-keep class !org.myorg.special { *; }
I would like to configure proguard to keep all classes except when they are from either of two packages, say org.myorg.special and org.myorg.another.
I have tried for instance
-keep class !(org.myorg.special,org.myorg.another) { *; }
but the above syntax is not supported by proguard.
What is the correct syntax?
-keep class ![org.myorg.special,org.myorg.another],org.** { *; }
Related
Using -keep does not keep methods and fields. They are obfuscated but I do not want to obfuscate some classes with methods and fields.
Rules used
-target '11'
-keep public class com.example.MyClass
If I use and proguards returns a class which Java Decompiler can not decompile (message 'Internal Error' after decompiling) e.g.
-keep public class com.example.MyClass {
<methods>;
<fields>;
}
I tried also [*;}.
Is there something wrong/bug with ProGuard Version 7.3.0 and using option target '11'?
-keep interface com.example.ApiContext { *; }
-keep abstract class com.example.ControlContext { *; }
-keep class com.example.CloseInstanceContext { *; }
I think 'abstract' was the problem, that it did not work.
I am using an external library(Picasso) from Jcenter in my Android application. I am implementing an interface of that library in my app. The problem is that proguard always strips the methods of the implemented interface in my app.
The interface defined in the external library is
public interface Callback {
void onSuccess();
void onError();
}
And i implement this interface in my code. When i run proguard and check my .class files, i find that there are no onSuccess and onError methods in my implemented class.
I have already added the configurations to skip all that external library completely in my proguard file by adding this
-keep class com.squareup.picasso.** {*;}
-dontwarn com.squareup.picasso.**
One way of preventing the above stripping is that i do this, where PicassoCallback is my implementation of Callback interface
-keep class com.package.className$PicassoCallback{
public void onSuccess();
public void onError();
}
But then i will have to do this for every implementation of the external interface in my project.
Any proguard configuration that can help me to prevent stripping the methods throughout my project?
You can configure ProGuard to keep all classes that implement the Callback interface using this rule:
-keep class ** implements com.squareup.picasso.Callback { *; }
Another way is to add the #Keep annotation to all of you callbacks, which basically tells ProGuard to not strip/modify them in any way.
Just add this line:
-keep interface com.squareup.picasso.** { *; }
after this one:
-keep class com.squareup.picasso.** {*;}
I use several squareup libs so I have the next configuration in my project:
-keep class com.squareup.** { *; }
-keep interface com.squareup.** { *; }
EDIT:
Some useful examples: https://www.guardsquare.com/en/proguard/manual/examples
In other words: what -keep commands should I use to tell Proguard to avoid obfuscating my classes that represent native libraries? (since JNA requires that the names match the equivalent native function, struct, etc.)
This is the rule I'm using for now:
-keepclassmembers class * extends com.sun.jna.** {
<fields>;
<methods>;
}
I still think there might be a better way to do it though.
For me worked as well
-keep class com.sun.jna.** { *; }
-keep class * implements com.sun.jna.** { *; }
I think I solved it using these rules instead, because it seems they need everything of the package to be de-obfuscated:
-keep class com.sun.jna.** { *; }
-keep class * implements com.sun.jna.** { *; }
JNA by default uses Library interface method names to look up native function names. Anything other than those should be able to withstand obfuscation.
If your tests include coverage of all JNA calls then you should be able to test this almost as fast as asking the question here.
EDIT
Consider this a comment, since I'm not prepared to offer "-keep" commands :)
You certainly must avoid elimination or reordering of any Structure fields.
I have an app that uses ActiveAndroid, a database ORM library, that relies on annotations.
#Table(name="test")
public class DatabaseItem extends ActiveRecordBase<DatabaseItem> {
public DatabaseItem(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
#Column(name="counter")
public int counter;
}
How do I get Proguard working nicely with this? Currently, I get errors about not finding a column name by ActiveAndroid when using Proguard. I guess it somehow mangles the annotation.
My relevant Proguard configuration:
#ActiveAndroid
-keep public class com.activeandroid.**
-keep public class * extends com.activeandroid.ActiveRecordBase
-keepattributes Column
-keepattributes Table
Column and Table aren't existing java class file attributes. You'll at least have to specify
-keepattributes *Annotation*
Cfr. the ProGuard manual.
In March 2013, Proguard version 4.9 was released, one of the fixes were:
Fixed overly aggressive shrinking of class annotations.
So make sure that your Proguard version is up to date and then use Eric Lafortune's solution:
-keepattributes *Annotation*
You can also use this configuration to store all class members that has a specific annotation:
-keepclassmembers class * {
#fully.qualified.package.AnnotationType *;
}
Solution was to keep all members of the library and the database classes
-keep class com.activeandroid.**
{
*;
}
-keep public class my.app.database.**
{
*;
}
-keepattributes Column
-keepattributes Table
For those only using Gradle, the solution is very similar (note the single quotes around the Annotation):
keep 'public class java.package.** { *; }'
keepattributes '*Annotation*'
This is especially useful if you are using JSON serialization annotations (e.g., Jackson or the like) in a vanilla Gradle project.
This what worked in my case:
-keep class com.activeandroid.** { *; }
-keep class com.activeandroid.**.** { *; }
-keep class * extends com.activeandroid.Model
-keep class * extends com.activeandroid.serializer.TypeSerializer
-keep public class * extends com.activeandroid.ActiveRecordBase
-keepattributes Column
-keepattributes Table
-keepattributes *Annotation*
-keepclasseswithmembers class * { #com.activeandroid.annotation.Column <fields>; }
I use in my project a piece of code as described here
http://lexandera.com/2009/01/extracting-html-from-a-webview/
I create the .apk file, install it on my device and it correctly works. If I try to use the obfuscation with proguard the project fails, the method showHTML(String html) of MyJavaScriptInterface is not reached.
My proguard configuration regarding that
-keep public class com.mypackage.MyClass.MyJavaScriptInterface
-keep public class * implements com.mypackage.MyClass.MyJavaScriptInterface
-keepclassmembers class * implements com.mypackage.MyClass.MyJavaScriptInterface {
<methods>;
}
according to this this answer Android proguard Javascript Interface problem.
SOLVED.
As Eric suggested, I changed the Proguard configuration file like this:
-keep public class com.mypackage.MyClass$MyJavaScriptInterface
-keep public class * implements com.mypackage.MyClass$MyJavaScriptInterface
-keepclassmembers class com.mypackage.MyClass$MyJavaScriptInterface {
<methods>;
}
Now my project works perfectly.
For API 17+ you also need to preserve the #JavascriptInterface annotations:
-keepattributes JavascriptInterface
http://developer.android.com/reference/android/webkit/JavascriptInterface.html
If MyJavaScriptInterface is an inner class of MyClass, ProGuard expects a fully qualified name com.mypackage.MyClass$MyJavaScriptInterface. The naming convention with $ is used in the compiled class files on which ProGuard operates. Note that ProGuard mentions class names in the configuration that it can't find in the input jar, suggesting that these names may have been misspelled.
-keepclassmembers class com.mypackage.MyClass$JavaScriptInterface {
public *;
}
Use only this. It works for me.
Those Who are laze to provide the entire package path.
-keepclassmembers class **.*$PaymentJavaScriptInterface{
public *;
}
As suggested by edit in question,
out of those suggestions,
only using
-keepclassmembers class com.mypackage.MyClass$MyJavaScriptInterface {
public *;
}
with Important -
For API 17+ to preserve #JavascriptInterface annotations:
-keepattributes JavascriptInterface
(Which was stopping my app to work on Marshmallow)