Enum parsing fails with moshi and R8

故事扮演 提交于 2021-01-28 10:43:40

问题


I have the following dependencies:

moshi-codegen: 1.10.0
kotlin: 1.4.10
Android Gradle Plugin: 4.0.1
R8 is enabled in the build.

At runtime, i got the following stacktrace when Moshi tries to parse enums

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$1.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$1.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)

According to the README, i do not have to add R8 rules manually, but maybe enums are exceptions?


回答1:


Yes enum should be treated a bit differently and there is currently a pending PR to update the README file (as of the time of writing) https://github.com/square/moshi/pull/1216.

You have 2 options:

  1. Add @JsonAdapter(generateAdapter = false) on top of your enum definition.
  2. Add a proguard rule to keep your enum's fields e.g.,
-keepclassmembers enum your.model.package.YourEnum {
    <fields>;
    **[] values();
}

Reason:

According to the code here https://github.com/square/moshi/blob/0c85eae34af00ecbee46beaa5b25fb4af00fb9f2/moshi/src/main/resources/META-INF/proguard/moshi.pro#L10, Enum field names are used by the integrated EnumJsonAdapter. Also values() is synthesized by the Kotlin compiler and is used by EnumJsonAdapter indirectly.

Also note on the same file that Moshi has generated a pre-made proguard rule which is inherited by your app:

-keepclassmembers @com.squareup.moshi.JsonClass class * extends java.lang.Enum {
    <fields>;
    **[] values();
}

This rule is basically applied to all classes annotated by the @JsonClass annotation, so if you add the annotation (Option#1), your class would be covered by this rule.

Alternatively if you don't want adding the annotation, you can add the rule specifically for your class aka Option#2.



来源:https://stackoverflow.com/questions/64068151/enum-parsing-fails-with-moshi-and-r8

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!