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.

Serializer for LocalDateTime not found

See original GitHub issue

I am getting this error at run time.

kotlinx.serialization.SerializationException: Serializer for class 'LocalDateTime' is not found.
Mark the class as @Serializable or provide the serializer explicitly.
	at kotlinx.serialization.internal.Platform_commonKt.serializerNotRegistered(Platform.common.kt:91)
	at kotlinx.serialization.ContextualSerializer.serializer(ContextualSerializer.kt:51)
	at kotlinx.serialization.ContextualSerializer.serialize(ContextualSerializer.kt:61)
	at kotlinx.serialization.json.internal.StreamingJsonEncoder.encodeSerializableValue(StreamingJsonEncoder.kt:211)
	at kotlinx.serialization.encoding.Encoder$DefaultImpls.encodeNullableSerializableValue(Encoding.kt:302)
	at kotlinx.serialization.encoding.AbstractEncoder.encodeNullableSerializableValue(AbstractEncoder.kt:18)
	at kotlinx.serialization.encoding.AbstractEncoder.encodeNullableSerializableElement(AbstractEncoder.kt:90)
	at xxx.dto.v2.AddressDTO$$serializer.serialize(AddressDTO.kt:11)
	at xxx.dto.v2.AddressDTO$$serializer.serialize(AddressDTO.kt:11)
	at kotlinx.serialization.json.internal.StreamingJsonEncoder.encodeSerializableValue(StreamingJsonEncoder.kt:211)
	at kotlinx.serialization.json.Json.encodeToString(Json.kt:80)
	at io.ktor.serialization.SerializationConverter.serializeContent(SerializationConverter.kt:141)
	at io.ktor.serialization.SerializationConverter.convertForSend(SerializationConverter.kt:128)
	at io.ktor.features.ContentNegotiation$Feature$install$2.invokeSuspend(ContentNegotiation.kt:192)
	at io.ktor.features.ContentNegotiation$Feature$install$2.invoke(ContentNegotiation.kt)
	at io.ktor.features.ContentNegotiation$Feature$install$2.invoke(ContentNegotiation.kt)
	at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:248)
	at io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:116)
	at io.ktor.util.pipeline.SuspendFunctionGun.execute(SuspendFunctionGun.kt:136)
	at io.ktor.util.pipeline.Pipeline.execute(Pipeline.kt:79)
	at xxx.api.v2.views.AccountDataV2$register$1$1.invokeSuspend(AccountDataV2.kt:75)
	at xxx.api.v2.views.AccountDataV2$register$1$1.invoke(AccountDataV2.kt)
	at xxx.api.v2.views.AccountDataV2$register$1$1.invoke(AccountDataV2.kt)
	at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:248)
	at io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:116)
	at io.ktor.features.StatusPages$interceptCall$2.invokeSuspend(StatusPages.kt:102)
	at io.ktor.features.StatusPages$interceptCall$2.invoke(StatusPages.kt)
	at io.ktor.features.StatusPages$interceptCall$2.invoke(StatusPages.kt)
	at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:89)
	at kotlinx.coroutines.CoroutineScopeKt.coroutineScope(CoroutineScope.kt:264)
	at io.ktor.features.StatusPages.interceptCall(StatusPages.kt:101)
	at io.ktor.features.StatusPages.access$interceptCall(StatusPages.kt:18)
	at io.ktor.features.StatusPages$Feature$install$2.invokeSuspend(StatusPages.kt:142)
	at io.ktor.features.StatusPages$Feature$install$2.invoke(StatusPages.kt)
	at io.ktor.features.StatusPages$Feature$install$2.invoke(StatusPages.kt)
	at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:248)
	at io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:116)
	at io.ktor.util.pipeline.SuspendFunctionGun.execute(SuspendFunctionGun.kt:136)
	at io.ktor.util.pipeline.Pipeline.execute(Pipeline.kt:79)
	at io.ktor.routing.Routing.executeResult(Routing.kt:155)
	at io.ktor.routing.Routing.interceptor(Routing.kt:39)
	at io.ktor.routing.Routing$Feature$install$1.invokeSuspend(Routing.kt:107)
	at io.ktor.routing.Routing$Feature$install$1.invoke(Routing.kt)
	at io.ktor.routing.Routing$Feature$install$1.invoke(Routing.kt)
	at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:248)
	at io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:116)
	at io.ktor.features.ContentNegotiation$Feature$install$1.invokeSuspend(ContentNegotiation.kt:145)
	at io.ktor.features.ContentNegotiation$Feature$install$1.invoke(ContentNegotiation.kt)
	at io.ktor.features.ContentNegotiation$Feature$install$1.invoke(ContentNegotiation.kt)
	at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:248)
	at io.ktor.util.pipeline.SuspendFunctionGun.access$loop(SuspendFunctionGun.kt:15)
	at io.ktor.util.pipeline.SuspendFunctionGun$continuation$1.resumeWith(SuspendFunctionGun.kt:93)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
	at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
	at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500)
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
	at io.ktor.server.netty.EventLoopGroupProxy$Companion.create$lambda-1$lambda-0(NettyApplicationEngine.kt:251)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.base/java.lang.Thread.run(Thread.java:831)

The common code DTO is as follows.

@file:UseContextualSerialization(LocalDateTime::class)
package xxx.dto.v2

import io.kvision.types.LocalDateTime
import kotlinx.serialization.UseContextualSerialization
import kotlinx.serialization.Serializable
import xxx.fields.ObjectId
import kotlin.js.ExperimentalJsExport
import kotlin.js.JsExport

@ExperimentalJsExport
@JsExport
@Serializable
data class AddressDTO (
    val id: ObjectId? = null,
    val addressLine1: String,
    val addressLine2: String,
    val suburb: String,
    val city: String,
    val region: String,
    val areaCode: String,
    val country: String,
    val googlePlaceId: String,
    var deleted: Boolean = false,
    var createdAt: LocalDateTime? = null,
    var updatedAt: LocalDateTime? = null
)

build.grade.kts commonMain

    sourceSets {
        val commonMain by getting {
            dependencies {
                api("io.kvision:kvision-server-ktor:$kvisionVersion")
            }
            kotlin.srcDir("build/generated-src/common")
        }

The values I am inserting into the DTO are from exposed DAO which are in java.time.LocalDateTime public final val createdAt: LocalDateTime /* = java.time.LocalDateTime / public final val updatedAt: LocalDateTime / = java.time.LocalDateTime */

I double checked my code against the examples and can find no real differences.

If I change to kotlinx-datetime to serialize the localdatetime instead of the kvision class I have no issues.

Do I need to explicitly set the Serilizer for the kvision LocalDateTime?

Issue Analytics

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

github_iconTop GitHub Comments

1reaction
drammeltcommented, Aug 17, 2021

EDIT: Fixed solution, previous one had issues on the Frontend.

In case anyone comes across this the solution was…

Tabulator Table Ajax -> Backend API Endpoint

Use the Serializer from Kvision in the Backend side

@Serializer(forClass = LocalDateTime::class)
actual object JsonLocalDateTimeSerializer : KSerializer<LocalDateTime> {
    override val descriptor: SerialDescriptor = buildClassSerialDescriptor("java.time.LocalDateTime")

    override fun deserialize(decoder: Decoder): LocalDateTime {
        @Suppress("MagicNumber")
        return LocalDateTime.parse(
            decoder.decodeString().split("[").first().dropLast(6),
            DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS")
        )
    }

    override fun serialize(encoder: Encoder, value: LocalDateTime) {
        encoder.encodeString(value.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS")))
    }
}

Duplicate the common DTO on the Backend and annotate with @file:UseSerializers(JsonLocalDateTimeSerializer::class) So it is serialised to the format expected by KVision.

And on the JS annotate the common DTO with @file:UseContextualSerialization(LocalDateTime::class)

Backend returns the Ajax DTO which will match the common code DTO and will be used without issue in the Kvision frontend.

0reactions
drammeltcommented, Aug 17, 2021

Yes you are correct this is an AJAX endpoint for a Tabulator table.

You are a lifesaver thank you!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Jackson/Kafka LocalDateTime serialization not working properly
apache.kafka.common.serialization.JsonSerializer class. It is only happening when reading from multiple topic/higher throughput. The exact ...
Read more >
Serializable/Serializer on expect/actual classes doesnt work
Both expect/acutal LocalDateSerializer and not LocalDate : Serializer for element of type LocalDate has not been found.
Read more >
Serialization - Noda Time
As of Noda Time 1.2, the following types implement IXmlSerializable and can therefore be serialized: Instant; OffsetDateTime; ZonedDateTime; LocalDateTime ...
Read more >
Jackson Error: Java 8 date/time type not supported by default
The error occurs when we serialize a Java object or deserialize JSON to POJO, and the POJO contains new Java 8 date time...
Read more >
Wildfly 22 to 23: Getting "Java 8 date/time type `java.time ...
LocalDate ` not supported by default" ... this error when trying to serialize Java 8 LocalDate and LocalDateTime objects. ... Am I missing...
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