Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Kotlin Serialization custom serializers #30870

Closed
severn-everett opened this issue Jul 11, 2023 · 2 comments
Closed

Support Kotlin Serialization custom serializers #30870

severn-everett opened this issue Jul 11, 2023 · 2 comments
Assignees
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) theme: kotlin An issue related to Kotlin support type: bug A general bug
Milestone

Comments

@severn-everett
Copy link

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.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Jul 11, 2023
@sdeleuze sdeleuze self-assigned this Jul 12, 2023
@sdeleuze sdeleuze added in: web Issues in web modules (web, webmvc, webflux, websocket) theme: kotlin An issue related to Kotlin support labels Jul 12, 2023
@sdeleuze
Copy link
Contributor

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?

@sdeleuze sdeleuze removed the status: waiting-for-triage An issue we've not yet triaged or decided on label Jul 12, 2023
@sdeleuze sdeleuze added this to the 6.1.0-M3 milestone Jul 12, 2023
@severn-everett
Copy link
Author

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")
}

@jhoeller jhoeller modified the milestones: 6.1.0-M3, 6.1.0-M4 Jul 17, 2023
@sdeleuze sdeleuze modified the milestones: 6.1.0-M4, 6.0.12 Aug 4, 2023
@sdeleuze sdeleuze added the type: bug A general bug label Aug 4, 2023
@sdeleuze sdeleuze changed the title KotlinSerializationSupport.serializer() ignores the SerializerModule of its own format attribute. Support Kotlin Serialization custom serializers Aug 4, 2023
sdeleuze added a commit to sdeleuze/spring-framework that referenced this issue Aug 4, 2023
This commit updates WebMVC converters and WebFlux
encoders/decoders to support custom serialization
serializers with Kotlin Serialization when specified
via a custom SerialFormat.

It also turns the serializers cache to a non-static
field in order to allow per converter/encoder/decoder
configuration.

Closes spring-projectsgh-30870
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) theme: kotlin An issue related to Kotlin support type: bug A general bug
Projects
None yet
Development

No branches or pull requests

4 participants