question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Kotlinx.Serialization: first level serialization is broken

See original GitHub issue

How to reproduce:

  1. Push a class with an instant to the Mongo collection
  2. Find from the mongo collection
  3. It should fail to deserialize

Expected Behavior

It should deserialize to the correct class

Actual Behavior

It fails to deserialize

Additional case specific information:

Java 11, OpenJDK. KMongo 4.2.1

Mongo Collection State:

db.schedulerJob.find()
{ "_id" : ObjectId("5fb7d2bfac8e4033d69c163f"), "startTime" : ISODate("2020-11-20T14:29:19.502Z"), "duration" : NumberLong(900000), "targetUserId" : "110433910835404800", "guildId" : "383210853270552578", "reason" : "Time's up!", "action" : "UNMUTE" }

Interface:

interface SchedulerJob {
    @Contextual @SerialName("_id") val id: Id<SchedulerJob>
    val action: Action
    @Contextual val startTime: Instant
    val duration: Long
    val targetUserId: String
    val guildId: String

    fun shouldBePersisted(): Boolean {
        return duration >= Duration.ofMinutes(15).toMillis()
    }

    suspend fun processJob()
}

Effective class:

@Serializable
class UnmuteSchedulerJob(
    @Contextual @SerialName("_id") override val id: Id<SchedulerJob> = newId(),
    @Contextual override val startTime: Instant = Instant.now(),
    override val duration: Long,
    override val targetUserId: String,
    override val guildId: String,
    val reason: String?
) : SchedulerJob {
    override val action: Action = Action.UNMUTE

    override suspend fun processJob() {
        val jda = KoinContextHandler.get().get<JDA>()
        val guild = jda.getGuildById(guildId) ?: return

        val moderationService = KoinContextHandler.get().get<IModerationService>()

        moderationService.unmute(targetUserId, guild, reason)
    }
}

Exception Log:

Exception in thread "pool-3-thread-1" org.bson.BsonInvalidOperationException: readString can only be called when CurrentBSONType is STRING, not when CurrentBSONType is DATE_TIME.
	at org.bson.AbstractBsonReader.verifyBSONType(AbstractBsonReader.java:690)
	at org.bson.AbstractBsonReader.checkPreconditions(AbstractBsonReader.java:722)
	at org.bson.AbstractBsonReader.readString(AbstractBsonReader.java:457)
	at com.github.jershell.kbson.FlexibleDecoder.decodeString(BsonFlexibleDecoder.kt:114)
	at kotlinx.serialization.encoding.AbstractDecoder.decodeStringElement(AbstractDecoder.kt:56)
	at kotlinx.serialization.internal.AbstractPolymorphicSerializer.deserialize(AbstractPolymorphicSerializer.kt:52)
	at kotlinx.serialization.encoding.Decoder$DefaultImpls.decodeSerializableValue(Decoding.kt:234)
	at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:17)
	at org.litote.kmongo.serialization.SerializationCodec.decode(SerializationCodec.kt:69)
	at com.mongodb.internal.operation.CommandResultArrayCodec.decode(CommandResultArrayCodec.java:52)
	at com.mongodb.internal.operation.CommandResultDocumentCodec.readValue(CommandResultDocumentCodec.java:60)
	at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:87)
	at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:42)
	at org.bson.internal.LazyCodec.decode(LazyCodec.java:48)
	at org.bson.codecs.BsonDocumentCodec.readValue(BsonDocumentCodec.java:104)
	at com.mongodb.internal.operation.CommandResultDocumentCodec.readValue(CommandResultDocumentCodec.java:63)
	at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:87)
	at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:42)
	at com.mongodb.internal.connection.ReplyMessage.<init>(ReplyMessage.java:51)
	at com.mongodb.internal.connection.InternalStreamConnection.getCommandResult(InternalStreamConnection.java:477)
	at com.mongodb.internal.connection.InternalStreamConnection.access$1000(InternalStreamConnection.java:78)
	at com.mongodb.internal.connection.InternalStreamConnection$2$1.onResult(InternalStreamConnection.java:462)
	at com.mongodb.internal.connection.InternalStreamConnection$2$1.onResult(InternalStreamConnection.java:440)
	at com.mongodb.internal.connection.InternalStreamConnection$MessageHeaderCallback$MessageCallback.onResult(InternalStreamConnection.java:745)
	at com.mongodb.internal.connection.InternalStreamConnection$MessageHeaderCallback$MessageCallback.onResult(InternalStreamConnection.java:712)
	at com.mongodb.internal.connection.InternalStreamConnection$5.completed(InternalStreamConnection.java:582)
	at com.mongodb.internal.connection.InternalStreamConnection$5.completed(InternalStreamConnection.java:579)
	at com.mongodb.internal.connection.AsynchronousChannelStream$BasicCompletionHandler.completed(AsynchronousChannelStream.java:250)
	at com.mongodb.internal.connection.AsynchronousChannelStream$BasicCompletionHandler.completed(AsynchronousChannelStream.java:233)
	at java.base/sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:127)
	at java.base/sun.nio.ch.Invoker.invokeDirect(Invoker.java:158)
	at java.base/sun.nio.ch.UnixAsynchronousSocketChannelImpl.implRead(UnixAsynchronousSocketChannelImpl.java:562)
	at java.base/sun.nio.ch.AsynchronousSocketChannelImpl.read(AsynchronousSocketChannelImpl.java:277)
	at java.base/sun.nio.ch.AsynchronousSocketChannelImpl.read(AsynchronousSocketChannelImpl.java:298)
	at com.mongodb.internal.connection.AsynchronousSocketChannelStream$AsynchronousSocketChannelAdapter.read(AsynchronousSocketChannelStream.java:144)
	at com.mongodb.internal.connection.AsynchronousChannelStream.readAsync(AsynchronousChannelStream.java:118)
	at com.mongodb.internal.connection.AsynchronousChannelStream.readAsync(AsynchronousChannelStream.java:107)
	at com.mongodb.internal.connection.InternalStreamConnection.readAsync(InternalStreamConnection.java:579)
	at com.mongodb.internal.connection.InternalStreamConnection.access$1100(InternalStreamConnection.java:78)
	at com.mongodb.internal.connection.InternalStreamConnection$MessageHeaderCallback.onResult(InternalStreamConnection.java:702)
	at com.mongodb.internal.connection.InternalStreamConnection$MessageHeaderCallback.onResult(InternalStreamConnection.java:687)
	at com.mongodb.internal.connection.InternalStreamConnection$5.completed(InternalStreamConnection.java:582)
	at com.mongodb.internal.connection.InternalStreamConnection$5.completed(InternalStreamConnection.java:579)
	at com.mongodb.internal.connection.AsynchronousChannelStream$BasicCompletionHandler.completed(AsynchronousChannelStream.java:250)
	at com.mongodb.internal.connection.AsynchronousChannelStream$BasicCompletionHandler.completed(AsynchronousChannelStream.java:233)
	at java.base/sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:127)
	at java.base/sun.nio.ch.UnixAsynchronousSocketChannelImpl.finishRead(UnixAsynchronousSocketChannelImpl.java:439)
	at java.base/sun.nio.ch.UnixAsynchronousSocketChannelImpl.finish(UnixAsynchronousSocketChannelImpl.java:191)
	at java.base/sun.nio.ch.UnixAsynchronousSocketChannelImpl.onEvent(UnixAsynchronousSocketChannelImpl.java:213)
	at java.base/sun.nio.ch.EPollPort$EventHandlerTask.run(EPollPort.java:306)
	at java.base/sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:834)

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:9 (5 by maintainers)

github_iconTop GitHub Comments

3reactions
zigzagocommented, Nov 27, 2020

There is a regression in the kotlinx.serialization KMongo codec: first level polymorphism serialization is broken (it works if the class is embedded in an other class). I’m going to release a 4.2.2 version.

0reactions
zigzagocommented, Nov 28, 2020

By the way I found an other annoying bug (see #249). Expect a new bug fix release in a few days (a fix on third-party library kbson is required)

Read more comments on GitHub >

github_iconTop Results From Across the Web

Kotlin @Serializable annotation not working in IntelliJ
I can build the project with Gradle, but it's showing up red in IntelliJ and when I hover on the @Serializable annotation, there's...
Read more >
Serialization: New player has joined - Bekk Christmas
kotlinx.serialization provides a framework for converting an object into a sequence of bits and bytes, and of course a way of converting it...
Read more >
Kotlin Serialization Episode 2: Add Kotlin Serialization Library
Add Kotlin Serialization Library: Explore the starter project and add required dependencies for Kotlin Serialization Library.
Read more >
kotlinx.serialization 1.0 by Leonid Startsev - YouTube
Recording brought to you by American Express. https://americanexpress.io/kotlin-jobsWe've released kotlinx. serialization 1.0.
Read more >
Android Data Serialization Tutorial with the Kotlin Serialization ...
Note: Don't let the name kotlinx.serialization mislead you: The library supports both serialization and deserialization. Naming things is hard, ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found