google / gson

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

IllegalStateException: TypeToken must be created when using GSON 2.10.1 and R8 on Android #2646

Closed snijsure closed 2 months ago

snijsure commented 4 months ago

Gson version

2.10.1

Java / Android version

Java 17, Android 34

Description

I just updated my Android project to use latest GSON library 2.10.1 and I am getting following exception, when using this library on Android project with AGP 8.1 and R8 enabled.

Caused by: java.lang.IllegalStateException: TypeToken must be created with a type argument: new TypeToken<...>() {}; When using code shrinkers (ProGuard, R8, ...) make sure that generic signatures are preserved.

Per this stackoverflow thread I need to add additional rules -- https://stackoverflow.com/questions/76224936/google-gson-preserve-generic-signatures

Perhaps a naive question -- shouldn't these rules be packaged with the library?

As consumer of GSON library, do I still need to explicitly include rules specified here in the file below, as far as I can tell those changes are merged.

https://github.com/google/gson/blob/main/gson/src/main/resources/META-INF/proguard/gson.pro

snijsure commented 4 months ago

Never mind found android documentation

Marcono1234 commented 4 months ago

shouldn't these rules be packaged with the library?

Yes you are right, and the gson.pro file you mentioned will be packaged in the JAR. However, those changes have not been released yet. They will be part of the upcoming version 2.11.0, see also #2632.

snijsure commented 4 months ago

@Marcono1234 thanks. I will keep this open. In my testing for my Android app at least I had to add following entries. I am using AGP 8.1.2 and retrofit 2.9.0

Those rules were previously recommended here.

https://github.com/google/gson/blob/main/gson/src/main/resources/META-INF/proguard/gson.pro

# Keep no-args constructor of classes which can be used with @JsonAdapter
# By default their no-args constructor is invoked to create an adapter instance
-keepclassmembers class * extends com.google.gson.TypeAdapter {
  <init>();
}
-keepclassmembers class * implements com.google.gson.TypeAdapterFactory {
  <init>();
}
-keepclassmembers class * implements com.google.gson.JsonSerializer {
  <init>();
}
-keepclassmembers class * implements com.google.gson.JsonDeserializer {
  <init>();
}

# Keep fields annotated with @SerializedName for classes which are referenced.
# If classes with fields annotated with @SerializedName have a no-args
# constructor keep that as well. Based on
# https://issuetracker.google.com/issues/150189783#comment11.
# See also https://github.com/google/gson/pull/2420#discussion_r1241813541
# for a more detailed explanation.
-if class *
-keepclasseswithmembers,allowobfuscation class <1> {
  @com.google.gson.annotations.SerializedName <fields>;
}
-if class * {
  @com.google.gson.annotations.SerializedName <fields>;
}
-keepclassmembers,allowobfuscation,allowoptimization class <1> {
  <init>();
}
Marcono1234 commented 2 months ago

Gson 2.11.0 has now been released (the release notes on GitHub will follow shortly). Please test if the newly included default R8 rules work for you and let us know about the result.

isles1217 commented 2 months ago

The included rules in 2.11.0 solved the issue for me, thanks!

eamonnmcmanus commented 2 months ago

Thanks for confirming!