11

i am using ProGuard in my project but its giving wrong data in new Gson().toJson(Request);

i am getting out put

{"a":"manage","b":"689184d4418b6d975d9a8e53105d3382","c":"10","d":"76"}

instead of

{"username":"manage","password":"689184d4418b6d975d9a8e53105d3382","value":"10","store":"76"}

My ProGuard rule

-dontwarn okio.**
-dontwarn retrofit2.Platform$Java8
-dontwarn sun.misc.Unsafe
-dontwarn org.w3c.dom.bootstrap.DOMImplementationRegistry
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions
-keepclassmembers class rx.internal.util.unsafe.** {
    long producerIndex;
    long consumerIndex;
}

-keepclasseswithmembers class * {
    @retrofit2.http.* <methods>;
}
-keep class com.google.gson.** { *; }
-keep class com.google.inject.** { *; }

and i am using

 compile 'com.squareup.retrofit2:converter-gson:2.0.0'

is there a new recommended ProGuard configuration for retrofit2:converter-gson in Android?

praj
  • 849
  • 1
  • 16
  • 39
  • the easiest would be to keep the classes that you wan to use with gson. otherwise you might want to look if gson has an annotation to give a field a name - this is how i do it in my app using jackson. – Dodge Jul 28 '16 at 09:09
  • how to keep the classes..Any rule – praj Jul 28 '16 at 09:11

5 Answers5

22

you either want to keep the class you are using with gson or use @SerializedName annotation.

option 1 (keep class)

// all classes in a package
-keep class com.example.app.json.** { *; }
// or a specific class
-keep class com.example.app.json.SpecificClass { *; }

option 2 (use @SerializedName):

public class YourJsonClass{
   @SerializedName("name") String username;

   public MyClass(String username) {
     this.username = username;
   }
 }

with the second option proguard still obfuscates the class and field names but gosn can use the annotation to get the correct name for each field

Dodge
  • 8,047
  • 2
  • 30
  • 45
8

Annotate your JSON model classes with @Keep.

Eugen Pechanec
  • 37,669
  • 7
  • 103
  • 124
  • @ralphgabb usually you provide two files with rules to proguard. One from the sdk and one from yoir project. The one from the sdk contains, among others, a rule to keep classes annotated with Keep. Make sure you have that. – Eugen Pechanec Jul 19 '18 at 07:11
5

Use android @Keep annotation on you desired class like authToken

@Keep
data class AuthToken(
    var access_token: String,
    var token_type: String,
    var expires_in: String,
    var userName: String,
    var issued: String,
    var expires: String) {}

And then in ProGuard add below line:
If using androidx

-keep @androidx.annotation.Keep public class *

Else

 -keep @android.support.annotation.Keep public class *
Ali mohammadi
  • 1,839
  • 26
  • 27
0

In my case, I was using Moshi for JSON with Retrofit, but the problem was the same. It worked in debug, but after building with ProGuard, the RecyclerView that used the model crashed with a NullPointerException, because the list was full of empty model objects, since Moshi didn't recognize any of the fields. I think the exact same thing happens with Gson.

One solution is to annotate every field with its corresponding serialized name:

@Json(name="username") String username;

That way ProGuard can obfuscate the variable names without breaking the conversion.

The other solution is adding a "keep" option like Dodge suggested, in the proguard-rules.pro file

-keep public class com.example.model.User
Alfonso
  • 76
  • 2
  • 4
0

If your using jsonschema2pojo every field is annotated with

@SerializedName(field)

Just add this to your proguard-rules.pro to keep every fieldname by it's @SerializedName.

-keepclassmembers,allowobfuscation class * {
  @com.google.gson.annotations.SerializedName <fields>;
}
S. Gissel
  • 1,788
  • 2
  • 15
  • 32