In KotlinSerializationSupport
:
@Nullable
protected final KSerializer<Object> serializer(ResolvableType resolvableType) {
Type type = resolvableType.getType();
KSerializer<Object> serializer = serializerCache.get(type);
if (serializer == null) {
try {
serializer = SerializersKt.serializerOrNull(type);
}
catch (IllegalArgumentException ignored) {
}
if (serializer != null) {
if (hasPolymorphism(serializer.getDescriptor(), new HashSet<>())) {
return null;
}
serializerCache.put(type, serializer);
}
}
return serializer;
}
the call serializer = SerializersKt.serializerOrNull(type);
generates an instance of EmptySerializersModule()
which - by definition - does not contain any information about custom serializers. Using format.getSerializersModule().serializerOrNull()
would allow the Kotlin serialization in WebFlux to use custom serializers for third-party classes as is possible for WebMVC's Kotlin serialization implementation.
Comment From: sdeleuze
Thanks for raising this, I tend to think it makes sense. From Java format.getSerializersModule().serializerOrNull()
looks innaccessible but SerializersKt.serializerOrNull(format.getSerializersModule(), type)
is.
Any simple repro available?
Comment From: severn-everett
Here's a repro of the two different serializerOrNull()
calls using Kotlinx Serialization and Spring Core:
import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.Json
import kotlinx.serialization.modules.SerializersModule
import kotlinx.serialization.serializerOrNull
import org.springframework.core.ResolvableType
import java.math.BigDecimal
object BigDecimalSerializer : KSerializer<BigDecimal> {
override val descriptor = PrimitiveSerialDescriptor("BigDecimal", PrimitiveKind.DOUBLE)
override fun deserialize(decoder: Decoder): BigDecimal = BigDecimal.valueOf(decoder.decodeDouble())
override fun serialize(encoder: Encoder, value: BigDecimal) {
encoder.encodeDouble(value.toDouble())
}
}
fun main() {
val bigDecimalType = ResolvableType.forClass(BigDecimal::class.java)
val json = Json {
serializersModule = SerializersModule {
contextual(BigDecimal::class, BigDecimalSerializer)
}
}
val bdType = bigDecimalType.type
val defaultSerializer = serializerOrNull(bdType)
val jsonSerializer = json.serializersModule.serializerOrNull(bdType)
println("SERIALIZERS: $defaultSerializer | $jsonSerializer")
}