Skip to content

Serialization works in JVM, but doesn't work in JS (LEGACY) #1448

Closed
@StarGuardian

Description

@StarGuardian

Describe the bug
I try to serialize sealed generic classes and it works well in JVM, but JS test fails

To Reproduce
My classes:

@Serializable
data class IntPayload(val value: Int)

@Serializable
sealed class OperationResult<out T>

typealias ActionResult = OperationResult<Unit>

@Serializable
@SerialName("operation_success")
data class OperationSuccess<T>(val result: T): OperationResult<T>()

@Serializable
@SerialName("operation_failure")
data class OperationFailure(val error: String): OperationResult<@Contextual Nothing>()

@Serializable
@SerialName("action_success")
object ActionSuccess: ActionResult()

Test:

class OperationResultSerializationTest {

    val jsonFormat = Json {
        serializersModule = SerializersModule {
            polymorphic(Any::class) {
                subclass(IntPayload::class)
            }
        }
    }

    @Test
    @JsName("operationSuccessSerializationTest")
    fun `operation success should be serialized and deserialized`() {
        val success = OperationSuccess(IntPayload(42))

        val successJson = serialize(success)
        val deserializedSuccess = deserialize<IntPayload>(successJson)

        DefaultAsserter.assertEquals(null, success, deserializedSuccess)
    }

    private inline fun <reified T> serialize(value: OperationResult<T>): String {
        return jsonFormat.encodeToString(value)
    }

    private inline fun <reified T> deserialize(json: String): OperationResult<T> {
        return jsonFormat.decodeFromString(json)
    }
}

When I run js test I get exception:

TypeError: tmp$.serializer is not a function
	at <global>.compiledSerializerImpl(C:/Users/Akela/AppData/Local/Temp/_karma_webpack_490920/commons.js:72080)
	at <global>.serializerOrNull(C:/Users/Akela/AppData/Local/Temp/_karma_webpack_490920/commons.js:67234)
	at <global>.reflectiveOrContextual(C:/Users/Akela/AppData/Local/Temp/_karma_webpack_490920/commons.js:67226)
	at <global>.builtinSerializer(C:/Users/Akela/AppData/Local/Temp/_karma_webpack_490920/commons.js:67220)
	at <global>.serializerByKTypeImpl(C:/Users/Akela/AppData/Local/Temp/_karma_webpack_490920/commons.js:67159)
	at <global>.serializer(C:/Users/Akela/AppData/Local/Temp/_karma_webpack_490920/commons.js:67129)
	at data.OperationResultSerializationTest.operationSuccessSerializationTest(C:/Users/Akela/AppData/Local/Temp/_karma_webpack_490920/commons.js:77540)
	at <global>.<unknown>(C:/Users/Akela/AppData/Local/Temp/_karma_webpack_490920/commons.js:77588)
	at Context.<anonymous>(C:/Users/Akela/AppData/Local/Temp/_karma_webpack_490920/commons.js:57)

If I use 1.1.0 version of library I get another exception:

SerializationException: Serializer for class 'OperationResult' is not found.
Mark the class as @Serializable or provide the serializer explicitly.
On Kotlin/JS explicitly declared serializer should be used for interfaces and enums without @Serializable annotation
	at Object.captureStack(C:/Users/Akela/AppData/Local/Temp/_karma_webpack_73575/commons.js:40068)
	at SerializationException.constructor(C:/Users/Akela/AppData/Local/Temp/_karma_webpack_73575/commons.js:40401)
	at SerializationException.constructor(C:/Users/Akela/AppData/Local/Temp/_karma_webpack_73575/commons.js:40427)
	at SerializationException.constructor(C:/Users/Akela/AppData/Local/Temp/_karma_webpack_73575/commons.js:40447)
	at IllegalArgumentException.init(C:/Users/Akela/AppData/Local/Temp/_karma_webpack_73575/commons.js:40458)
	at SerializationException.init(C:/Users/Akela/AppData/Local/Temp/_karma_webpack_73575/commons.js:67048)
	at <global>.platformSpecificSerializerNotRegistered(C:/Users/Akela/AppData/Local/Temp/_karma_webpack_73575/commons.js:72030)
	at <global>.serializer(C:/Users/Akela/AppData/Local/Temp/_karma_webpack_73575/commons.js:67125)
	at data.OperationResultSerializationTest.operationSuccessSerializationTest(C:/Users/Akela/AppData/Local/Temp/_karma_webpack_73575/commons.js:77226)
	at <global>.<unknown>(C:/Users/Akela/AppData/Local/Temp/_karma_webpack_73575/commons.js:77274)

Simple project to show the issue. Just clone it and run gradlew check
https://github.com/StarGuardian/kotlin-js-serialization-bug

Expected behavior
Both tests (for JVM and JS) passes

Environment

  • Kotlin version: 1.5.0 (tried 1.4.32 as well)
  • Library version: 1.2.0 (tried 1.1.0 as well)
  • Kotlin platforms: JVM and JS
  • Gradle version: 6.6.1
  • Windows 7

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