google / gson

A Java serialization/deserialization library to convert Java Objects into JSON and back
Apache License 2.0
23.37k stars 4.28k forks source link

GSON not able to parse on a release build #1632

Open harshmittal29 opened 4 years ago

harshmittal29 commented 4 years ago

When I generate release build, GSON is not able to parse my API response.

I am using retrofit and gson Parser. com.squareup.retrofit2:retrofit com.squareup.retrofit2:converter-gson Retrofit version 2.6.0

implementation "com.google.code.gson:gson:$rootProject.gsonVersion" Version : '2.8.5'

My proguard for GSON

# removes such information by default, so configure it to keep all of it.
-keepattributes Signature

# For using GSON @Expose annotation

-keepattributes EnclosingMethod

# Gson specific classes
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.stream.** { *; }
-dontwarn com.google.gson.internal.UnsafeAllocator

# Gson specific classes
-dontwarn sun.misc.**

# Prevent proguard from stripping interface information from TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
-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>;

Proguard for retrofit2

# Retrofit 2.X
## https://square.github.io/retrofit/ ##

# Retrofit does reflection on generic parameters. InnerClasses is required to use Signature and
# EnclosingMethod is required to use InnerClasses.
-keepattributes Signature, InnerClasses, EnclosingMethod

# Retrofit does reflection on method and parameter annotations.
-keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations

# Retain service method parameters when optimizing.
-keepclassmembers,allowshrinking,allowobfuscation interface * {
    @retrofit2.http.* <methods>;
}

# Ignore annotation used for build tooling.
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement

# Ignore JSR 305 annotations for embedding nullability information.
-dontwarn javax.annotation.**

# Guarded by a NoClassDefFoundError try/catch and only used when on the classpath.
-dontwarn kotlin.Unit

# Top-level functions that can only be used by Kotlin.
-dontwarn retrofit2.KotlinExtensions
-dontwarn retrofit2.KotlinExtensions$*

# With R8 full mode, it sees no subtypes of Retrofit interfaces since they are created with a Proxy
# and replaces all potential values with null. Explicitly keeping the interfaces prevents this.
-if interface * { @retrofit2.http.* <methods>; }
-keep,allowobfuscation interface <1>

I am using R8 enabled compilation

# Enables R8 for Android Library modules only.
android.enableR8.libraries = true
# Enables R8 for all modules.
android.enableR8 = true

But when I include my models in proguard, the parsing seems to work

# Application classes from libraries that will be serialized/deserialized over Gson
 -keep class com.mindvalley.loginmodule.model.** { <fields>; }
 -keep class com.mindvalley.module_videoplayer.model.** { <fields>; }
 -keep class com.mindvalley.mva.model.** { <fields>; }

Can someone suggest how can I make parsing work without including models inside proguard?

marcosybarraa commented 4 years ago

Hi ! I had same issue, after 2 days investigating I discovered it is related with minify true in your graddle.

If is your case, you have to add all classes you use on the parse of GSON to your proguard-rules.txt

-keepattributes Signature -keep class sun.misc.Unsafe { *; } -keep class com.your.Package.yourclases.** { *; } Hope it helps. Kind regards

harshmittal29 commented 4 years ago

@marcosybarraa yes added classes to proguard rules work. Is there a more cleaner way to do this without adding the classes? Adding classes manually can induce errors. Any other way GSON team is aware of?

yfdcme commented 4 years ago

you need to keep those JavaBean files with -keep while gson not supportted.

Canato commented 4 years ago

Any news on this? We enable R8 and start to get this problem, and keep all our data classes is not something practical, Thanks

Marcono1234 commented 2 years ago

The R8 FAQ contains hints for usage with Gson. In general if you notice specific information being missing in the android-proguard-example of Gson, it would be good to create an issue or pull request for this.