Prevent class member name obfuscation by ProGuard
Solution 1
Thanks Waqas!
I find solution for my case:
-optimizationpasses 5
-dump class_files.txt
-printseeds seeds.txt
-printusage unused.txt
-printmapping mapping.txt
-optimizations !code/simplification/arithmetic,!field/*,!class/merging*/
-allowaccessmodification
-repackageclasses ''
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.MapActivity
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-libraryjars libs/commons-io-2.2.jar
-libraryjars libs/gson-2.2.2.jar
-keep public class org.apache.commons.io.**
-keep public class com.google.gson.**
-keep public class com.google.gson.** {public private protected *;}
##---------------Begin: proguard configuration for Gson ----------
-keepattributes *Annotation*,Signature
-keep class com.mypackage.ActivityMonitor.ClassMultiPoints.** { *; }
-keep public class com.mypackage.ActivityMonitor$ClassMultiPoints { public protected *; }
-keep public class com.mypackage.ActivityMonitor$ClassMultiPoints$ClassPoints { public protected *; }
-keep public class com.mypackage.ActivityMonitor$ClassMultiPoints$ClassPoints$ClassPoint { public protected *; }
# To support Enum type of class members
-keepclassmembers enum * { *; }
##---------------End: proguard configuration for Gson ----------
Also I don't use @SerializedName("message")
in my class, aboved config work fine without serialization.
Solution 2
If you dont want your class members to be obfuscated then use SerializedName
annotation provided by Gson. For example:
public class ClassMultiPoints
{
@SerializedName("message")
public String message;
@SerializedName("data")
public List<ClassPoints> data;
...
}
Moreover, make sure you do add proper proguard configuration for Gson library too. For example:
##---------------Begin: proguard configuration for Gson ----------
# Gson uses generic type information stored in a class file when working with
#fields. Proguard removes such information by default, so configure it to keep
#all of it.
-keepattributes Signature
# For using GSON @Expose annotation
-keepattributes *Annotation*
# Gson specific classes
-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { *; }
##---------------End: proguard configuration for Gson ----------
For more info read this.
Solution 3
I also found I need to -keepclassmembers
when using Dexguard's optimise option. Without this several of my model objects failed to deserialise
##---------------Begin: proguard configuration for Gson ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# For using GSON @Expose annotation
-keepattributes *Annotation*
# Application classes that will be serialized/deserialized over Gson, keepclassmembers
-keep class com.myapp.model.** { *; }
-keepclassmembers class com.myapp.model.** { *; }
Solution 4
If you use the @Expose
annotation like I do, you can tell ProGuard to keep any field annotated with it:
# keep anything annotated with @Expose
-keepclassmembers public class * {
@com.google.gson.annotations.Expose *;
}
# Also keep classes that @Expose everything
-keep @com.google.gson.annotations.Expose public class *
Solution 5
To exclude your class from obfuscation, Keep the attributes of InnerClasses, keep your class and keep the class members of the class eg.
-keepattributes InnerClasses
-keep class com.yourproject.YourClass**
-keepclassmembers class com.yourproject.YourClass** {
*;
}
For more information http://proguard.sourceforge.net/manual/examples.html
Related videos on Youtube
Tapa Save
Updated on July 08, 2022Comments
-
Tapa Save almost 2 years
I have my class
ClassMultiPoint
with subclasses.public class ClassMultiPoints { public String message; public List<ClassPoints> data; public class ClassPoints { public String id; public List<ClassPoint> points; public class ClassPoint { public String speed; public String bearing; } } }
I will get value of object
oPoints
from parseGSON
:oPoints = gson.fromJson( jsonString, ClassMultiPoints.class);
I try use
oPoints.message
.When I run my application without
proguard
app run success. When I run my app withproguard
my app crash.I think problem is:
proguard
rename attribute'oPoints.message'
of my class to short'a'
.I try keep the names of the methods and attributes is constant, but
proguard
rename its:proguard.cfg:
-injars bin/classes -injars libs -outjars bin/classes-processed.jar -dontpreverify -repackageclasses '' -allowaccessmodification -optimizations !code/simplification/arithmetic -keepattributes *Annotation* -dontskipnonpubliclibraryclasses -optimizationpasses 5 -printmapping map.txt -flattenpackagehierarchy -keep public class * extends android.app.Activity -keep public class * extends android.app.Application -keep public class * extends android.app.MapActivity -keep public class * extends android.app.Service -keep public class * extends android.content.BroadcastReceiver -keep public class * extends android.content.ContentProvider -libraryjars libs/commons-io-2.2.jar -libraryjars libs/ftp4j-1.7.1.jar -libraryjars libs/gson-2.2.2.jar -keep public class org.apache.commons.io.** -keep public class it.sauronsoftware.ftp4j.** -keep public class com.google.gson.** -keep public class com.mypackagename.ActivityMonitor$* -keep public class * extends android.view.View { public <init>(android.content.Context); public <init>(android.content.Context, android.util.AttributeSet); public <init>(android.content.Context, android.util.AttributeSet, int); public void set*(...); } -keepclasseswithmembers class * { public <init>(android.content.Context, android.util.AttributeSet); } -keepclasseswithmembers class * { public <init>(android.content.Context, android.util.AttributeSet, int); } -keepclassmembers class * extends android.content.Context { public void *(android.view.View); public void *(android.view.MenuItem); } -keepclassmembers class * implements android.os.Parcelable { static android.os.Parcelable$Creator CREATOR; } -keepclassmembers class **.R$* { public static <fields>; }
What is right way to keep names of the methods and attributes of the my one (static) class?
-
umesh about 10 years-keep class com.google.gson.examples.android.model.** { *; } it works for me but when i applied reverse engg on apk, i got all the model classes with not change in members, it breaks the security purpose, isn't there any other option, we can obfuscate model too ?
-
waqaslam about 10 yearsare you using
@SerializedName
annotation on top of your class members? because if you do then you don't need to bypass custom class obfuscation in proguard config like you are doing withcom.google.gson.examples.android.model.** { *; }
. -
umesh about 10 yearsno, actually i wanted to obfuscate it. but now i realized that if the fields names change, then they won't match json key, so the gson could not parse it.
-
waqaslam about 10 yearsexactly... and that's why we need to use @SerializedName
-
Oliver Dixon about 9 yearsIs this option available for the whole class?
-
waqaslam about 9 years@iLoveUnicorns for that you need to tweak the proguard config to ignore obfuscating the entire class.
-
Marian Klühspies over 8 yearsI don´t know if it really matters, but in general using Annotations with Runtime Policy on Android can be a performance issue. I would recommend using the -keep options of Proguard instead
-
Muhammad Younas over 6 years@iDroid Explorer I use apkTool to test the release apk but obfuscation did not work for me it did not rename the classes
-
Tapa Save over 6 yearsThis settings allow NOT obfuscate the code. Are you need obfuscate code?
-
Muhammad Younas over 6 yearsyes this code is not obfuscate or I am testing wrong release apk
-
Mirjalal over 5 yearsspecial thanks for
-keepclassmembers class com.myapp.model.** { *; }
. despite of I am using jackson lib rather than gson, that line helped me! Thanks. -
Anton Kazakov almost 5 yearsAccording to GSON javadoc @Expose can target fields only. So second instruction seems useless