Edge case where R8 removes the TypeToken's generic type (while consuming the library's recently updated proguard rules)
alipov opened this issue · 0 comments
(Originally reported here).
Gson version
2.10.1 + those proguard rules.
Java / Android version
I have tested on Android 34.
Used tools
- Gradle; version: 8.2
- R8; version: 8.2.47
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.