Skip to content

java.lang.NoSuchFieldException for kotlin enums with ProGuard (and R8 enabled) #1776

@k-liakhovskii-hs

Description

@k-liakhovskii-hs

Hey, we noticed that we are getting java.lang.NoSuchFieldException when we use the latest sample rules on ProGuard with R8 enabled. Please find more details below.

Example of Enum definition:

enum class NetworkMessageTypeDTO{
    @SerializedName("IG_STORY") IG_STORY_1,
    @SerializedName("IG_FEED") IG_FEED
}

Stack trace is:

java.lang.AssertionError: java.lang.NoSuchFieldException: IG_STORY_1
        at com.google.gson.internal.bind.TypeAdapters$EnumTypeAdapter.<init>(TypeAdapters.java:12)
        at com.google.gson.internal.bind.TypeAdapters$30.create(TypeAdapters.java:5)
        at com.google.gson.Gson.n(Gson.java:9)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.a(ReflectiveTypeAdapterFactory.java:4)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.d(ReflectiveTypeAdapterFactory.java:15)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:4)
        at com.google.gson.Gson.n(Gson.java:9)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.a(ReflectiveTypeAdapterFactory.java:4)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.d(ReflectiveTypeAdapterFactory.java:15)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:4)
        at com.google.gson.Gson.n(Gson.java:9)
        at s.r.a.a.b(GsonConverterFactory.java:1)
        at s.n.i(Retrofit.java:6)

We use the sample rules, including the following R8 change:

...
# Prevent R8 from leaving Data object members always null
-keepclassmembers,allowobfuscation class * {
  @com.google.gson.annotations.SerializedName <fields>;
}

WORKAROUND:
It looks like the actual problem is not in SerializedName, but in binding between it and the real enum case. Removing of allowobfuscation in the rules above solves this issue as it stops obfuscating the names of enum cases. But not sure if that is a proper change, or the problem is in implementation of ReflectiveTypeAdapter.

It seems that the issue is related to the EnumTypeAdapter binding here. Looks like similar issues were highlighted here and here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions