Moshi 1.9.x не может сериализовать котлинский тип - PullRequest
1 голос
/ 03 ноября 2019

После обновления до Моши 1.9.1 (из 1.8.0 ) я сталкиваюсь со следующим аварийным завершением и трассировкой стека:

java.lang.IllegalArgumentException: Cannot serialize Kotlin type com.garpr.android.data.models.RankedPlayer. Reflective serialization of Kotlin classes without using kotlin-reflect has undefined and unexpected behavior. Please use KotlinJsonAdapter from the moshi-kotlin artifact or use code gen from the moshi-kotlin-codegen artifact.
for class com.garpr.android.data.models.RankedPlayer
for class com.garpr.android.data.models.AbsPlayer

    at com.squareup.moshi.Moshi$LookupChain.exceptionWithLookupStack(Moshi.java:349)
    at com.squareup.moshi.Moshi.adapter(Moshi.java:150)
    at com.squareup.moshi.Moshi.adapter(Moshi.java:98)
    at com.squareup.moshi.AdapterMethodsFactory$AdapterMethod.bind(AdapterMethodsFactory.java:313)
    at com.squareup.moshi.AdapterMethodsFactory.create(AdapterMethodsFactory.java:62)
    at com.squareup.moshi.Moshi.adapter(Moshi.java:138)
    at com.squareup.moshi.Moshi.adapter(Moshi.java:98)
    at com.squareup.moshi.Moshi.adapter(Moshi.java:72)
    at com.garpr.android.data.converters.AbsPlayerConverterTest.setUp(AbsPlayerConverterTest.kt:76)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.robolectric.RobolectricTestRunner$HelperTestRunner$1.evaluate(RobolectricTestRunner.java:546)
    at org.robolectric.internal.SandboxTestRunner$2.lambda$evaluate$0(SandboxTestRunner.java:252)
    at org.robolectric.internal.bytecode.Sandbox.lambda$runOnMainThread$0(Sandbox.java:89)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.IllegalArgumentException: Cannot serialize Kotlin type com.garpr.android.data.models.RankedPlayer. Reflective serialization of Kotlin classes without using kotlin-reflect has undefined and unexpected behavior. Please use KotlinJsonAdapter from the moshi-kotlin artifact or use code gen from the moshi-kotlin-codegen artifact.
    at com.squareup.moshi.ClassJsonAdapter$1.create(ClassJsonAdapter.java:83)
    at com.squareup.moshi.Moshi.nextAdapter(Moshi.java:169)
    at com.squareup.moshi.AdapterMethodsFactory$AdapterMethod.bind(AdapterMethodsFactory.java:312)
    at com.squareup.moshi.AdapterMethodsFactory.create(AdapterMethodsFactory.java:62)
    at com.squareup.moshi.Moshi.adapter(Moshi.java:138)
    ... 23 more

Iвидел этот другой ответ о переполнении стека , но он ко мне не относится, так как я уже добавил соответствующую строку @JsonClass(generateAdapter = X) в мои классы.

Я использую пользовательский AbsPlayerConverter class для моего AbsPlayer класса, он используется, чтобы я мог определить, к какому подклассу разрешить. И затем, если он разрешается в RankedPlayer, я использую другой настраиваемый конвертер для этого (RankedPlayerConverter).

Вот мой код Моши-строителя](https://github.com/charlesmadere/smash-ranks-android/blob/a66d118f33c23b7a655d10da21630f909abd3639/smash-ranks-android/app/src/main/java/com/garpr/android/koin/MiscModule.kt#L26):

Moshi.Builder()
        .add(AbsPlayerConverter)
        .add(AbsRegionConverter)
        .add(AbsTournamentConverter)
        .add(MatchConverter)
        .add(RankedPlayerConverter)
        .add(SimpleDateConverter)
        .build()

А вот Моши в моем файле Gradle :

implementation "com.squareup.moshi:moshi:1.9.1"
kapt "com.squareup.moshi:moshi-kotlin-codegen:1.9.1"

Итак, наконец, после всего этого текста и информации, у меня естьПонятия не имею, как я могу столкнуться с этим сбоем. Я четко определил, как сериализовать / десериализовать мой класс RankedPlayer. И если я понижаю до Moshi 1.8.0 и оставляю свою кодовую базу полностью как есть, этот сбой исчезает ивсе работает без нареканий.

У кого-нибудь есть идеи?

Спасибо !!

1 Ответ

1 голос
/ 03 ноября 2019

В сообщении об ошибке конкретно указывается Please use KotlinJsonAdapter from the moshi-kotlin artifact or use code gen from the moshi-kotlin-codegen artifact

В соответствии с частью Kotlin файла readme , вы должны добавить KotlinJsonAdapterFactory, если вы не используете кодер Моши. Это было определенное изменение поведения в Moshi 1.9 согласно сообщению в блоге о Moshi 1.9 .

Moshi.Builder()
    .add(AbsPlayerConverter)
    .add(AbsRegionConverter)
    .add(AbsTournamentConverter)
    .add(MatchConverter)
    .add(RankedPlayerConverter)
    .add(SimpleDateConverter)
    .add(KotlinJsonAdapterFactory())
    .build()

И убедитесь, что вы используете implementation("com.squareup.moshi:moshi-kotlin:1.9.1")

...