proguard
proguard copied to clipboard
Shrink stage did not consider the reference in Signature, resulting in loss of generic information
my code just like this: ` OuterModel outerModel = new Gson().fromJson("{"test":[{"url":"google.com"}]}", OuterModel.class); UrlModel urlModel= outerModel.subUrlModels.get(0);
public class OuterModel {
@SerializedName("test")
public List<SubUrlModel> subUrlModels;
public List<SubUrlModel> getSubUrlModels() {
return subUrlModels;
}
public void setSubUrlModels(List<SubUrlModel> subUrlModels) {
this.subUrlModels = subUrlModels;
}
}
class SubUrlModel extends UrlModel {
}
`
SubUrlModel is a empty class that extends UrlModel, UrlModel is a common model class。
after I use proguard to process the code, I encountered the following error: java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to com.bytedance.android.model.UrlModel
I found that the SubUrlModel class was deleted, and the generic information was modified. But it is not correct, it is Objetct, it should actually be UrlModel
``
Hi @threeloe ! Thanks for the report.
~~This seems like a known limitation with Gson optimization. There is a known limitation listed in the manual for GSON optimizations that's relevant here~~
ProGuard can not optimize the following use cases of Gson: ...
- Serializing classes that have generic type variables in their signature.
You should be able to disable GSON optimization and instead use -keep
rules for the model classes e.g.
-optimizations !library/gson
-keep class com.example.*Model {*; }
@mrjameshamilton Thanks for the reply, I think this is not an error in the optimization phase, but a problem in the shrink phase. The problem can still be reproduced by adding the following configuration
-dontoptimize -dontobfuscate
Of course, keep SubUrlModel can solve my problem
Indeed, you're right - I've checked further and the problem is shrinking. ProGuard cannot tell that SubUrlModel
is used because it is used through reflection via Gson.
Since SubUrlModel
is unused; the ClassShrinker
changes the signature attribute here. It changes signature types to java/lang/Object
if the existing class is unused; ideally it would change it to the next used super-type but currently it's not the case.
So, indeed the workaround here is to keep the SubUrlModel
class to prevent it from being shrunk.