You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
TL;DR: When using kotlin serialization with a polymorphic hierarchy, the REST server expects a discriminator value. This discriminator value is not created when using the Quarkus REST-Client (see MessageBodyWriter of the quarkus-rest-kotlin-serialization dependency here).
The following exception will be thrown:
2024-12-02 10:58:08,062 ERROR [io.qua.ver.htt.run.QuarkusErrorHandler] (executor-thread-1) HTTP Request to /hello failed, error id: 978f9b51-4ea3-4c94-9869-3e2a5419a93f-1: kotlinx.serialization.json.internal.JsonDecodingException: Class discriminator was missing and no default serializers were registered in the polymorphic scope of 'Person'.
JSON input: {"name":"Max"}
at kotlinx.serialization.json.internal.JsonExceptionsKt.JsonDecodingException(JsonExceptions.kt:24)
at kotlinx.serialization.json.internal.JsonExceptionsKt.JsonDecodingException(JsonExceptions.kt:32)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:412)
at kotlinx.serialization.json.internal.JsonStreamsKt.decodeByReader(JsonStreams.kt:111)
at kotlinx.serialization.json.JvmStreamsKt.decodeFromStream(JvmStreams.kt:61)
at io.quarkus.resteasy.reactive.kotlin.serialization.runtime.KotlinSerializationMessageBodyReader.doReadFrom(KotlinSerializationMessageBodyReader.kt:57)
at io.quarkus.resteasy.reactive.kotlin.serialization.runtime.KotlinSerializationMessageBodyReader.readFrom(KotlinSerializationMessageBodyReader.kt:50)
at org.jboss.resteasy.reactive.server.handlers.RequestDeserializeHandler.readFrom(RequestDeserializeHandler.java:126)
at org.jboss.resteasy.reactive.server.handlers.RequestDeserializeHandler.handle(RequestDeserializeHandler.java:84)
at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:135)
at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:147)
at io.quarkus.vertx.core.runtime.VertxCoreRecorder$15.runWith(VertxCoreRecorder.java:637)
at org.jboss.threads.EnhancedQueueExecutor$Task.doRunWith(EnhancedQueueExecutor.java:2675)
at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2654)
at org.jboss.threads.EnhancedQueueExecutor.runThreadBody(EnhancedQueueExecutor.java:1627)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1594)
at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:11)
at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:11)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:1583)
Expected behavior
When the serialization of a polymorphic hierarchy takes place on the client-side, the discriminator value is added.
In my example below, a workaround can be done by adding the following provider (and probably overwriting the default provider) which considers the super class:
The discriminator value is missing. The problem is that the MessageBodyWriter of the quarkus-rest-kotlin-serialization dependency (see here) receives in the writeTo function the sub class instead of the super class. And when serializing the sub class, the discriminator value will be ignored.
I was involved too in the finding. While the MessageBodyWriter shown in the Expected Behaviour section solves the problem, this doesn't quite cut it, if the superclass is an interface. We talked about it today and the approach would not work anymore more than one interface used.
The actual question, where we don't have an answer to, is why the type or genericType parameter is IdentifiedPerson instead of Person. I would assume that the type provided when calling the writeTo method is the type found in the method of the client interface (GreetingInterface).
If someone could shed some light on how this should work, then I'm sure we can come up with a proper proposal to fix it.
The handling of type and genericType is mandated by the JAX-RS / Jakarta REST specification and in my experience, if any change were maded to these, a ton of stuff would break
Describe the bug
TL;DR: When using kotlin serialization with a polymorphic hierarchy, the REST server expects a discriminator value. This discriminator value is not created when using the Quarkus REST-Client (see
MessageBodyWriter
of thequarkus-rest-kotlin-serialization
dependency here).The following exception will be thrown:
Expected behavior
When the serialization of a polymorphic hierarchy takes place on the client-side, the discriminator value is added.
In my example below, a workaround can be done by adding the following provider (and probably overwriting the default provider) which considers the super class:
Actual behavior
The discriminator value is missing. The problem is that the
MessageBodyWriter
of thequarkus-rest-kotlin-serialization
dependency (see here) receives in thewriteTo
function the sub class instead of the super class. And when serializing the sub class, the discriminator value will be ignored.How to Reproduce?
The code can be found here.
Output of
uname -a
orver
Linux prech 6.1.0-28-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.119-1 (2024-11-22) x86_64 GNU/Linux
Output of
java -version
java 21.0.2 2024-01-16 LTS Java(TM) SE Runtime Environment (build 21.0.2+13-LTS-58) Java HotSpot(TM) 64-Bit Server VM (build 21.0.2+13-LTS-58, mixed mode, sharing)
Quarkus version or git rev
3.17.2
Build tool (ie. output of
mvnw --version
orgradlew --version
)Gradle 8.9
Additional information
No response
The text was updated successfully, but these errors were encountered: