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

Edge case where R8 removes the TypeToken's generic type (while consuming the library's recently updated proguard rules) #2658

Open alipov opened 4 months ago

alipov commented 4 months ago

(Originally reported here).

Gson version

2.10.1 + those proguard rules.

Java / Android version

I have tested on Android 34.

Used tools

Description

@Marcono1234 First of all thanks a lot for introducing consumer proguard rules!

I have added the rules to one of my projects. Everything seemed to work fine, but I ran into one issue.
Here's a sample code that makes use of Gson's TypeToken:

private List<? extends MyInterface> getData() {
    String input = "[{\"value\": \"data\"}]";
    Type type = new TypeToken<List<MyImplementation>>() { }.getType();
    return new Gson().fromJson(input, type);
}

MyImplementation class implements the MyInterface interface, and this is its only usage in code.

Upon minification, R8 removes the MyImplementation class completely, while TypeToken is being left with java.lang.Object as its generic argument:

.class Linfo/osom/typetokenminify/a;
.super Lh/a;
.source "SourceFile"

# annotations
.annotation system Ldalvik/annotation/Signature;
    value = {
        "Lh/a<",
        "Ljava/util/List<",
        "Ljava/lang/Object;",
        ">;>;"
    }
.end annotation

This, in turn, causes a runtime exception:

Caused by: java.lang.ClassCastException
    at c.a.a(SourceFile:1)
    at info.osom.typetokenminify.MainActivity.onCreate(SourceFile:163)

As a workaround, I currently have to explicitly keep the class:

-keep,allowobfuscation,allowoptimization class info.osom.typetokenminify.MyImplementation {
  @com.google.gson.annotations.SerializedName <fields>;
}

I'm wondering if more general rule can be used in such cases.

Expected behavior

Run the application without errors.

Actual behavior

The application crash at runtime.

Reproduction steps

I have uploaded a sample project for demonstration.