moshi 和 R8 枚举解析失败
Enum parsing fails with moshi and R8
我有以下依赖项:
moshi-codegen: 1.10.0
科特林:1.4.10
Android Gradle 插件:4.0.1
R8 已在构建中启用。
在运行时,当 Moshi 尝试解析枚举时,我得到了以下堆栈跟踪
java.lang.AssertionError: Missing field in e.f.a.k.c.b.a
at com.squareup.moshi.StandardJsonAdapters$EnumJsonAdapter.<init>(SourceFile:246)
at com.squareup.moshi.StandardJsonAdapters.create(SourceFile:67)
at com.squareup.moshi.Moshi.adapter(SourceFile:141)
at com.tsystems.tpay.data.client.models.ContactApiModelJsonAdapter.<init>(SourceFile:30)
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
at com.squareup.moshi.internal.Util.generatedAdapter(SourceFile:553)
at com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory.create(SourceFile:193)
at com.squareup.moshi.Moshi.adapter(SourceFile:141)
at com.squareup.moshi.Moshi.adapter(SourceFile:101)
at com.squareup.moshi.Moshi.adapter(SourceFile:71)
at com.squareup.moshi.CollectionJsonAdapter.newArrayListAdapter(SourceFile:52)
at com.squareup.moshi.CollectionJsonAdapter.create(SourceFile:36)
at com.squareup.moshi.Moshi.adapter(SourceFile:141)
at com.squareup.moshi.Moshi.adapter(SourceFile:101)
at p.z.a.a.a(SourceFile:91)
at p.u.a(SourceFile:352)
at p.u.b(SourceFile:335)
at p.k.a(SourceFile:113)
at p.k.a(SourceFile:82)
at p.v.a(SourceFile:37)
at p.u.a(SourceFile:192)
at p.u$a.invoke(SourceFile:149)
at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
at $Proxy14.c(Unknown Source)
at e.f.a.k.b.f$g.a(SourceFile:87)
at i.b0.j.a.a.b(SourceFile:33)
at j.a.v0.run(SourceFile:241)
at j.a.g3.a.a(SourceFile:594)
at j.a.g3.a.a(SourceFile:60)
at j.a.g3.a$b.run(SourceFile:740)
Caused by: java.lang.NoSuchFieldException: PERSONAL
at java.lang.Class.getField(Class.java:1604)
at com.squareup.moshi.StandardJsonAdapters$EnumJsonAdapter.<init>(SourceFile:240)
根据 README,我不必手动添加 R8 规则,但也许枚举是例外?
是的,应该对枚举进行一些不同的处理,目前有一个待定的 PR 来更新 README 文件(截至撰写本文时)https://github.com/square/moshi/pull/1216。
您有 2 个选择:
- 在您的枚举定义之上添加
@JsonClass(generateAdapter = false)
。
- 添加混淆规则以保留您的枚举字段,例如
-keepclassmembers enum your.model.package.YourEnum {
<fields>;
**[] values();
}
原因:
根据这里的代码https://github.com/square/moshi/blob/0c85eae34af00ecbee46beaa5b25fb4af00fb9f2/moshi/src/main/resources/META-INF/proguard/moshi.pro#L10,集成的EnumJsonAdapter
使用了枚举字段名称。此外 values()
由 Kotlin 编译器合成并由 EnumJsonAdapter
间接使用。
另请注意同一文件,Moshi 生成了一个 pre-made proguard 规则,该规则由您的应用继承:
-keepclassmembers @com.squareup.moshi.JsonClass class * extends java.lang.Enum {
<fields>;
**[] values();
}
此规则基本上适用于所有由 @JsonClass
注释注释的 classes,因此如果您添加注释(选项#1),您的 class 将被覆盖这条规则。
或者,如果您不想添加注释,您可以添加专门针对您的 class aka Option#2 的规则。
我有以下依赖项:
moshi-codegen: 1.10.0
科特林:1.4.10
Android Gradle 插件:4.0.1
R8 已在构建中启用。
在运行时,当 Moshi 尝试解析枚举时,我得到了以下堆栈跟踪
java.lang.AssertionError: Missing field in e.f.a.k.c.b.a
at com.squareup.moshi.StandardJsonAdapters$EnumJsonAdapter.<init>(SourceFile:246)
at com.squareup.moshi.StandardJsonAdapters.create(SourceFile:67)
at com.squareup.moshi.Moshi.adapter(SourceFile:141)
at com.tsystems.tpay.data.client.models.ContactApiModelJsonAdapter.<init>(SourceFile:30)
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
at com.squareup.moshi.internal.Util.generatedAdapter(SourceFile:553)
at com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory.create(SourceFile:193)
at com.squareup.moshi.Moshi.adapter(SourceFile:141)
at com.squareup.moshi.Moshi.adapter(SourceFile:101)
at com.squareup.moshi.Moshi.adapter(SourceFile:71)
at com.squareup.moshi.CollectionJsonAdapter.newArrayListAdapter(SourceFile:52)
at com.squareup.moshi.CollectionJsonAdapter.create(SourceFile:36)
at com.squareup.moshi.Moshi.adapter(SourceFile:141)
at com.squareup.moshi.Moshi.adapter(SourceFile:101)
at p.z.a.a.a(SourceFile:91)
at p.u.a(SourceFile:352)
at p.u.b(SourceFile:335)
at p.k.a(SourceFile:113)
at p.k.a(SourceFile:82)
at p.v.a(SourceFile:37)
at p.u.a(SourceFile:192)
at p.u$a.invoke(SourceFile:149)
at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
at $Proxy14.c(Unknown Source)
at e.f.a.k.b.f$g.a(SourceFile:87)
at i.b0.j.a.a.b(SourceFile:33)
at j.a.v0.run(SourceFile:241)
at j.a.g3.a.a(SourceFile:594)
at j.a.g3.a.a(SourceFile:60)
at j.a.g3.a$b.run(SourceFile:740)
Caused by: java.lang.NoSuchFieldException: PERSONAL
at java.lang.Class.getField(Class.java:1604)
at com.squareup.moshi.StandardJsonAdapters$EnumJsonAdapter.<init>(SourceFile:240)
根据 README,我不必手动添加 R8 规则,但也许枚举是例外?
是的,应该对枚举进行一些不同的处理,目前有一个待定的 PR 来更新 README 文件(截至撰写本文时)https://github.com/square/moshi/pull/1216。
您有 2 个选择:
- 在您的枚举定义之上添加
@JsonClass(generateAdapter = false)
。 - 添加混淆规则以保留您的枚举字段,例如
-keepclassmembers enum your.model.package.YourEnum {
<fields>;
**[] values();
}
原因:
根据这里的代码https://github.com/square/moshi/blob/0c85eae34af00ecbee46beaa5b25fb4af00fb9f2/moshi/src/main/resources/META-INF/proguard/moshi.pro#L10,集成的EnumJsonAdapter
使用了枚举字段名称。此外 values()
由 Kotlin 编译器合成并由 EnumJsonAdapter
间接使用。
另请注意同一文件,Moshi 生成了一个 pre-made proguard 规则,该规则由您的应用继承:
-keepclassmembers @com.squareup.moshi.JsonClass class * extends java.lang.Enum {
<fields>;
**[] values();
}
此规则基本上适用于所有由 @JsonClass
注释注释的 classes,因此如果您添加注释(选项#1),您的 class 将被覆盖这条规则。
或者,如果您不想添加注释,您可以添加专门针对您的 class aka Option#2 的规则。