Skip to content

Moshi Polymorphic adapter fails on Kotlin 2.0 scripts #1878

Open
@franvis

Description

@franvis

We are facing an issue with one of our kotlin scripts that uses a polymorphic adapter after starting to run it with Kotlin 2.0.

The exception we get is:

java.lang.IllegalStateException: Incomplete hierarchy for class TestBlockA, unresolved classes [TestBlock]
        at kotlin.reflect.jvm.internal.impl.descriptors.runtime.components.RuntimeErrorReporter.reportIncompleteHierarchy(RuntimeErrorReporter.kt:26)
        at kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedClassDescriptor$DeserializedClassTypeConstructor.computeSupertypes(DeserializedClassDescriptor.kt:250)
        at kotlin.reflect.jvm.internal.impl.types.AbstractTypeConstructor.supertypes$lambda$0(AbstractTypeConstructor.kt:78)
        at kotlin.reflect.jvm.internal.impl.types.AbstractTypeConstructor.accessor$AbstractTypeConstructor$lambda0(AbstractTypeConstructor.kt)
        at kotlin.reflect.jvm.internal.impl.types.AbstractTypeConstructor$$Lambda$0.invoke(Unknown Source)
        at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedLazyValue.invoke(LockBasedStorageManager.java:408)
        at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedLazyValueWithPostCompute.invoke(LockBasedStorageManager.java:481)
        at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedNotNullLazyValueWithPostCompute.invoke(LockBasedStorageManager.java:512)
        at kotlin.reflect.jvm.internal.impl.types.AbstractTypeConstructor.getSupertypes(AbstractTypeConstructor.kt:27)
        at kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedClassDescriptor$DeserializedClassMemberScope.getNonDeclaredVariableNames(DeserializedClassDescriptor.kt:360)
        at kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedMemberScope$OptimizedImplementation.variableNames_delegate$lambda$9(DeserializedMemberScope.kt:262)
        at kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedMemberScope$OptimizedImplementation.accessor$DeserializedMemberScope$OptimizedImplementation$lambda4(DeserializedMemberScope.kt)
        at kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedMemberScope$OptimizedImplementation$$Lambda$4.invoke(Unknown Source)
        at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedLazyValue.invoke(LockBasedStorageManager.java:408)
        at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedNotNullLazyValue.invoke(LockBasedStorageManager.java:527)
        at kotlin.reflect.jvm.internal.impl.storage.StorageKt.getValue(storage.kt:42)
        at kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedMemberScope$OptimizedImplementation.getVariableNames(DeserializedMemberScope.kt:261)
        at kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedMemberScope$OptimizedImplementation.addFunctionsAndPropertiesTo(DeserializedMemberScope.kt:349)
        at kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedMemberScope.computeDescriptors(DeserializedMemberScope.kt:115)
        at kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedClassDescriptor$DeserializedClassMemberScope.allDescriptors$lambda$2(DeserializedClassDescriptor.kt:279)
        at kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedClassDescriptor$DeserializedClassMemberScope.accessor$DeserializedClassDescriptor$DeserializedClassMemberScope$lambda1(DeserializedClassDescriptor.kt)
        at kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedClassDescriptor$DeserializedClassMemberScope$$Lambda$1.invoke(Unknown Source)
        at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedLazyValue.invoke(LockBasedStorageManager.java:408)
        at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedNotNullLazyValue.invoke(LockBasedStorageManager.java:527)
        at kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedClassDescriptor$DeserializedClassMemberScope.getContributedDescriptors(DeserializedClassDescriptor.kt:289)
        at kotlin.reflect.jvm.internal.impl.resolve.scopes.ResolutionScope$DefaultImpls.getContributedDescriptors$default(ResolutionScope.kt:50)
        at kotlin.reflect.jvm.internal.KDeclarationContainerImpl.getMembers(KDeclarationContainerImpl.kt:58)
        at kotlin.reflect.jvm.internal.KClassImpl$Data.declaredNonStaticMembers_delegate$lambda$22(KClassImpl.kt:173)
        at kotlin.reflect.jvm.internal.KClassImpl$Data.accessor$KClassImpl$Data$lambda10(KClassImpl.kt)
        at kotlin.reflect.jvm.internal.KClassImpl$Data$$Lambda$10.invoke(Unknown Source)
        at kotlin.reflect.jvm.internal.ReflectProperties$LazySoftVal.invoke(ReflectProperties.java:70)
        at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:32)
        at kotlin.reflect.jvm.internal.KClassImpl$Data.getDeclaredNonStaticMembers(KClassImpl.kt:173)
        at kotlin.reflect.jvm.internal.KClassImpl$Data.allNonStaticMembers_delegate$lambda$26(KClassImpl.kt:182)
        at kotlin.reflect.jvm.internal.KClassImpl$Data.accessor$KClassImpl$Data$lambda14(KClassImpl.kt)
        at kotlin.reflect.jvm.internal.KClassImpl$Data$$Lambda$14.invoke(Unknown Source)
        at kotlin.reflect.jvm.internal.ReflectProperties$LazySoftVal.invoke(ReflectProperties.java:70)
        at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:32)
        at kotlin.reflect.jvm.internal.KClassImpl$Data.getAllNonStaticMembers(KClassImpl.kt:182)
        at kotlin.reflect.full.KClasses.getMemberProperties(KClasses.kt:148)
        at com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory.create(KotlinJsonAdapter.kt:234)
        at com.squareup.moshi.Moshi.adapter(Moshi.java:146)
        at com.squareup.moshi.Moshi.adapter(Moshi.java:106)
        at com.squareup.moshi.Moshi.adapter(Moshi.java:75)
        at com.squareup.moshi.adapters.PolymorphicJsonAdapterFactory.create(PolymorphicJsonAdapterFactory.java:216)
        at com.squareup.moshi.Moshi.adapter(Moshi.java:146)
        at com.squareup.moshi.Moshi.adapter(Moshi.java:106)
        at com.squareup.moshi.Moshi.adapter(Moshi.java:75)
        at com.squareup.moshi.CollectionJsonAdapter.newArrayListAdapter(CollectionJsonAdapter.java:54)
        at com.squareup.moshi.CollectionJsonAdapter$1.create(CollectionJsonAdapter.java:38)
        at com.squareup.moshi.Moshi.adapter(Moshi.java:146)
        at com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory.create(KotlinJsonAdapter.kt:292)
        at com.squareup.moshi.Moshi.adapter(Moshi.java:146)
        at com.squareup.moshi.Moshi.adapter(Moshi.java:106)
        at com.squareup.moshi.Moshi.adapter(Moshi.java:80)
        at Moshi_test_main.<init>(moshi_test.main.kts:51)

As an example, the following script will fail with the same exception we have:

#!/usr/bin/env kotlin
@file:DependsOn(
    "com.squareup.moshi:moshi:1.15.1",
    "com.squareup.moshi:moshi-kotlin:1.15.1",
    "com.squareup.moshi:moshi-adapters:1.15.1"
)

import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.JsonClass
import com.squareup.moshi.Moshi
import com.squareup.moshi.adapters.PolymorphicJsonAdapterFactory
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory

@JsonClass(generateAdapter = false)
sealed class TestBlock(open val type: String)

@JsonClass(generateAdapter = false)
data class TestPayload(val blocks: List<TestBlock>)

@JsonClass(generateAdapter = false)
data class TestBlockA(val text: String) : TestBlock(type = "test_a")

@JsonClass(generateAdapter = false)
data class TestBlockB(val elements: List<String>) : TestBlock(type = "test_b")

val adapter: JsonAdapter<TestPayload> =
    Moshi.Builder()
        .add(
            PolymorphicJsonAdapterFactory.of(TestBlock::class.java, "type")
                .withSubtype(TestBlockA::class.java, "test_a")
                .withSubtype(TestBlockB::class.java, "test_b")
        )
        .add(KotlinJsonAdapterFactory()).build().adapter(TestPayload::class.java)

Kotlin 2.0 scripts have known issues with nested classes and self references:

Is this related? Any advice on a workaround for it?

Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions