6

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?

WonderCsabo
  • 11,947
  • 13
  • 63
  • 105
  • Can you check you mapping file - what proguard did with your enum class? – Eugen Martynov Sep 26 '20 at 05:59
  • Basically, moshi fails here https://github.com/square/moshi/blob/master/moshi/src/main/java/com/squareup/moshi/StandardJsonAdapters.java#L277. That gives me impression enum should not be obfuscated. I'm trying to find moshi proguard configuration. Can you check in the library jar? – Eugen Martynov Sep 26 '20 at 06:01

1 Answers1

13

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 @JsonClass(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.

gmk57
  • 839
  • 11
  • 20
H.Nguyen
  • 1,621
  • 5
  • 19
  • 31