ProGuard for Android and GSON

37,986

Solution 1

I think most of those settings you have there are already included in the Android SDK by default.

So you can remove most of them, just leaving in the section devoted to GSON.


I am developing in Eclipse using Android SDK Tools 22.6.3 & whatever version of ProGuard ships with that.

Here's what I'm using for GSON 2.2.4 (as per their 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

# 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 mypersonalclass.data.model.** { *; }

It looks exactly the same as what you have, except I don't need the line about the annotations.


You can see I've commented out some classes that I added myself. If you serialize/deserialize your own classes, you need to declare them here in place of the reference to mypersonalclass.data.model. This is really important, as you don't want ProGuard to obfuscate the field or class names that GSON uses for serialization.

I always leave those types of comments in there, so I know how to configure the next library or app.

Solution 2

The previous answer stopped working for me recently probably due to some changes in Android (R8 is used now instead of Proguard). The configuration I use now is as follows (source - GSON examples):

##---------------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
-dontwarn sun.misc.**
#-keep class com.google.gson.stream.** { *; }

# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { <fields>; }

# Prevent proguard from stripping interface information from TypeAdapter, TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
-keep class * implements com.google.gson.TypeAdapter
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer

# Prevent R8 from leaving Data object members always null
-keepclassmembers,allowobfuscation class * {
  @com.google.gson.annotations.SerializedName <fields>;
}

##---------------End: proguard configuration for Gson  ----------

I found out that classes whose fields are annotated by @SerializedName do not have to be explicitly listed unless they are inner classes.

Solution 3

In my case, I just used GSON for deserializing JSON to an Object. So it was enough to add the following line to proguard file.

-keep class your.data.object.modals.package.** { <fields>; }

Solution 4

In my case I added the above but still got an error until in my app level gradle I changed compile 'org.immutables:gson:2.4.6' to provided 'org.immutables:gson:2.4.6'. Maybe someone more enlightened can explain why but this solved my problem.

Solution 5

Using -keep is a bad practice and you should never do it .You almost never want to use -keep; if you do need a ProGuard rule, you usually want one of the more specific variants

-keepclassmembers - This protects only the members of the class from shrinking and obfuscation.

-keepnames - This allows shrinking for classes and members, but not obfuscation. That is, any unused code is going to get removed. But the code that is kept will keep its original names.

-keepclassmembernames - Unused classes are removed, the remaining classes are renamed, unused members of those classes are removed, but then the remaining members keep their original names.

For more information please read this

PS - this is what I did for Gson

-keepclassmembernames class rscom.pojo.** { <fields>; }
Share:
37,986

Related videos on Youtube

AtariPete
Author by

AtariPete

Mobile Software Developer in the NYC area. Typically Blackberry, Android and iPhone development. I'm cofounder of Perk Mobile Inc. where we do mobile consulting and development. Also I organized the last MobileCampNYC3 event at Microsoft's NYC offices.

Updated on July 09, 2022

Comments

  • AtariPete
    AtariPete almost 2 years

    I'm setting up ProGuard for my Android project. My project also uses GSON.

    I've researched ProGuard configurations for compatibility with GSON and Android and came across this example offered by google-gson https://code.google.com/p/google-gson/source/browse/trunk/examples/android-proguard-example/proguard.cfg.

    ProGuard config copied below:

    ##---------------Begin: proguard configuration common for all Android apps ----------
    -optimizationpasses 5
    -dontusemixedcaseclassnames
    -dontskipnonpubliclibraryclasses
    -dontskipnonpubliclibraryclassmembers
    -dontpreverify
    -verbose
    -dump class_files.txt
    -printseeds seeds.txt
    -printusage unused.txt
    -printmapping mapping.txt
    -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
    
    -allowaccessmodification
    -keepattributes *Annotation*
    -renamesourcefileattribute SourceFile
    -keepattributes SourceFile,LineNumberTable
    -repackageclasses ''
    
    -keep public class * extends android.app.Activity
    -keep public class * extends android.app.Application
    -keep public class * extends android.app.Service
    -keep public class * extends android.content.BroadcastReceiver
    -keep public class * extends android.content.ContentProvider
    -keep public class * extends android.app.backup.BackupAgentHelper
    -keep public class * extends android.preference.Preference
    -keep public class com.android.vending.licensing.ILicensingService
    -dontnote com.android.vending.licensing.ILicensingService
    
    # Explicitly preserve all serialization members. The Serializable interface
    # is only a marker interface, so it wouldn't save them.
    -keepclassmembers class * implements java.io.Serializable {
        static final long serialVersionUID;
        private static final java.io.ObjectStreamField[] serialPersistentFields;
        private void writeObject(java.io.ObjectOutputStream);
        private void readObject(java.io.ObjectInputStream);
        java.lang.Object writeReplace();
        java.lang.Object readResolve();
    }
    
    # Preserve all native method names and the names of their classes.
    -keepclasseswithmembernames class * {
        native <methods>;
    }
    
    -keepclasseswithmembernames class * {
        public <init>(android.content.Context, android.util.AttributeSet);
    }
    
    -keepclasseswithmembernames class * {
        public <init>(android.content.Context, android.util.AttributeSet, int);
    }
    
    # Preserve static fields of inner classes of R classes that might be accessed
    # through introspection.
    -keepclassmembers class **.R$* {
      public static <fields>;
    }
    
    # Preserve the special static methods that are required in all enumeration classes.
    -keepclassmembers enum * {
        public static **[] values();
        public static ** valueOf(java.lang.String);
    }
    
    -keep public class * {
        public protected *;
    }
    
    -keep class * implements android.os.Parcelable {
      public static final android.os.Parcelable$Creator *;
    }
    ##---------------End: proguard configuration common for all Android apps ----------
    
    ##---------------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  ----------
    

    Questions:

    1. I see that this file has not been updated since 2011, is it still recommended for use? I ask because Android/GSON has changed quite a bit since then so I don't know how much of the above in unnecessary or incorrect.

    2. If this is not recommended, is there a new recommended ProGuard configuration for GSON in Android?

  • caw
    caw over 9 years
    This is where it's from, by the way: google-gson.googlecode.com/svn/trunk/examples/…
  • Noundla Sandeep
    Noundla Sandeep over 8 years
    After searching lots of QA.. I reached here. It makes me happy. Thanks Richard. one note, "mypersonalclass.data.model" this is not required for me. just check.
  • Richard Le Mesurier
    Richard Le Mesurier over 8 years
    @Noundla updated answer to explain that mypersonalclass.data.model is placeholder text and should point at your own data model package.
  • Tejzeratul
    Tejzeratul about 8 years
    links are broken now
  • Muhammad Babar
    Muhammad Babar over 7 years
    {*;} this was the main thing (as it will also keep the members of the class from obfuscation) in -keep class mypersonalclass.data.model.** { *; }. Also remove the #.
  • Miha_x64
    Miha_x64 about 7 years
    -keep Unsafe makes no sense, it is a framework class.
  • Richard Le Mesurier
    Richard Le Mesurier about 7 years
    Probably not, but in 2014 it was required in the config. @Miha_x64
  • art
    art over 4 years
    Alternatively, annotate your class with @Keep and proguard won't modify it.
  • RESTfulGeoffrey
    RESTfulGeoffrey about 4 years
    Thanks a ton, had a model in a different package and needed to add that path!
  • gmk57
    gmk57 almost 4 years
    What are the reasons behind "using -keep is a bad practice and you should never do it"? BTW, keepclassmembernames doesn't work in our setup, all fields are removed. Only keep or keepclassmembers really keeps them.
  • lasec0203
    lasec0203 almost 4 years
    only one * is needed.