I want to know if its possible to keep the name of a public static inner Class but renaming the parent classname.
My code looks like this:
public class MyDao extends AbstractDao {
public static final String TABLENAME = "BOX_DOWNLOAD";
public static class Properties {
public final static Property ID = new Property(0, Long.class, "ID", true, "ID");
public final static Property Name = new Property(1, String.class, "name", false, "NAME");
public final static Property Done = new Property(2, Boolean.class, "done", false, "DONE");
// SOME MORE CONSTANTS
};
// SOME CODE WHICH CAN BE OBFUSCATED
}
I want ProGuard to replace:
MyDao (the className)
the PROPERTIES' variables (ID, Name, Done)
I want ProGuard NOT to replace:
TABLENAME (variable name)
PROPERTIES (className only)
I tried this
-keepclassmembers class * extends de.greenrobot.dao.AbstractDao {
public static <fields>;
public static class *;
}
But this is not working. The classNames are not obfuscated.
// EDIT
I forgot to say that there are several classes like MyDao. Eg. MyDao1, MyDao2, etc.
I want to use wildcards.
Cfr. ProGuard manual > Usage > Keep Options
-keepclassmembers class de.greenrobot.dao.MyDao {
String TABLENAME;
}
-keep class de.greenrobot.dao.MyDao$Properties
Update: When keeping the name "MyDao$Properties", the current version of ProGuard appears to keep the name "MyDao" as well (even if the InnerClasses attribute is not preserved). This is somewhat more conservative than strictly necessary.
I have made following scripts, which works for me.
-keep class my.dao.package.*$Properties {
public static <fields>;
}
-keepclassmembers class my.dao.package.** {
public java.lang.String TABLENAME;
}
I have used wildcard for inner classes, which worked.
Related
I have the following location in my project:
package com.example.data
Where I have placed four classes, A, B, C and D that look like this:
public class A {
public List<B> bList = new ArrayList<>();
}
public class B {
public List<C> CList = new ArrayList<>();
}
public class C {
public D d;
}
public class D {
public String s;
}
Now, in my ProGuard I can add simething like this:
-keepclassmembers class com.example.data.data.A{*;}
-keepclassmembers class com.example.data.data.B{*;}
-keepclassmembers class com.example.data.data.C{*;}
-keepclassmembers class com.example.data.data.D{*;}
But is there a more simpler way I can avoid obfuscation in my classes configuration?
You can give a rule to the package level. So all classes under this package will not be obfuscated. In your proguard rules file, for example in proguard-common.pro file, add the below code.
-keep class com.example.data.** { *; }
I have an interface named EnumInt and using it as below
case EnumInt:
#SuppressWarnings("unchecked")
Class<? extends EnumInt> enumType = (Class<? extends EnumInt>) field.getType();
Method enumStaticMethod = enumType.getMethod("fromVal", int.class);
Object enumInstance = enumStaticMethod.invoke(null, object);
field.setAccessible(true);
field.set(entity, enumInstance);
break;
I have already keep whole package in progaurd but still getting
-keep class abc.cde.** { *; } // package having EnumInt interface and other files
java.lang.NoSuchMethodException: fromVal [int]
at java.lang.Class.getMethod(Class.java:2068)
at java.lang.Class.getMethod(Class.java:1690)
I have tried Keeping EnumInt Interface, All native method, fields in proguard for preventing obfuscation but still unable to remove error.
Please note without proguard it is working fine.
Please help. Thanks in advance. Problem is specific to Enums.
Answering my own question for the future readers.
I was using another enum implementing EnumInt like below
public static enum CustomeType implements EnumInt {
ALL(MSG_TYPE_ALL),
IN(MSG_TYPE_IN),
OUT(MSG_TYPE_OUT),
int val;
private CustomeType(int val) {
this.val = val;
}
public static CustomeType fromVal(int val) {
for (CustomeType messageType : values()) {
if (messageType.val == val) {
return messageType;
}
}
return null;
}
}
and i was missing the proguard obfuscation to prevent this enum.
Solution
Below line in proguard
-keep public enum abc.cde.a.CustomeType$** {
**[] $VALUES;
public *;
}
How to keep static method name unchanged and obfuscate everything inside the method.
Example code:
public class MyClass {
public static void MyFunc(Conetext context, String str, int i) {
Toast.makeText(context, "Hello world "+ str + i, Toast.LENGTH_SHORT).show();
}
}
Here I want to keep MyFunc unchanged.
Amit Vaghela why are you doing this? If you don't understand what I asked please ignore my post.
Do you think -keepclassmembernames will obfuscate entire code inside the MyFunc? I tested:
-optimizationpasses 5
-keep,allowobfuscation class *
-keepclassmembers class * {
public static void * (...);
}
And it didn't work and that's why I am here to ask. If you cannot help you better ignore it.
package com.hello
public class Outer extends Activity{
int a;
int b;
array c;
Boolean bol;
public void onCreate() {
a=1;
b=2;
c=new int[10];
bol=true;
}
class Inner implements Runnable {
public void run() {
if (bol)
for (int e=0;e<10;e++) c[e]=a+b;
}
}
}
How can I tell Progruad to keep the name of the inner class and the variables used in the inner class even though they are defined in the onCreate method?
I don't want to list each variable one by one.
to keep inner classes:
# specific class (in brackets for example we keep all)*
-keep class OuterFQNClassName$InnerClassName { *; }
# all inner classes of outer class
-keep class OuterFQNClassName$** { *; }
# all inner classes
-keepattributes InnerClasses
to keep fields with desired public/protected/private/default access level modifiers):
# for specific class
-keepclassmembers class FQNClassName {
protected <fields>;
}
# for all classes
-keepclassmembers class * {
protected <fields>;
}
# other approach for default acl
# be careful as method could have also native modifiers :)
-keepclassmembers class * {
!public !protected !private *;
}
*naming convention with a '$' separator between the names of inner classes and outer classes
please study a proguard docs:
https://www.guardsquare.com/en/proguard/manual/attributes
For my Android instrumentation test I need a few extra entry point into my classes. Those methods are not used in the actual application. My idea was to start them all with test_ and have a general rule to exclude them from being optimized away. This is how far I got:
-keepclassmembers class com.xxx.**.* {
public ** test_* ();
public ** test_* (**);
public static ** test_* ();
public static ** test_* (**);
}
But it still does not work. public static void test_destroy (final android.content.Context context) and private void dropTables (final SQLiteDatabase db) has just been removed from the code. And I have no idea why.
How is it properly used for wildcard patterns?
The solution is
-keepclassmembers class com.XXX.**.* {
*** test_* (...);
}
Another way to do this is to use an annotation (i.e. guava's #VisibleForTesting) to mark those methods. Then in proguard you can keep all entry points and members with that annotation:
-keep #com.google.common.annotations.VisibleForTesting class *
-keepclasseswithmembers class * {
#com.google.common.annotations.VisibleForTesting *;
}