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

kotlinx.serialization should not be used for Java interfaces implemented by Java classes #26298

Closed
mickael-coquer opened this issue Dec 18, 2020 · 8 comments
Assignees
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: bug A general bug
Milestone

Comments

@mickael-coquer
Copy link

Affects: 5.3.2


Having both Jackson and kotlinx.serialization in the classpath, kotlinx.serialization will try to deserialize Java interfaces implemented by Java classes resulting in the following exception:

org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Polymorphic serializer was not found for missing class discriminator ('null')
... nested exception is kotlinx.serialization.json.internal.JsonDecodingException: Polymorphic serializer was not found for missing class discriminator ('null')

The issue comes from the KotlinSerializationJsonHttpMessageConverter.candRead() method that returns true when the Type is a Java interface.

In case of Java concrete implementations, this method should return false and let Jackson handle the conversion.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Dec 18, 2020
@sdeleuze sdeleuze added this to the 5.3.3 milestone Dec 18, 2020
@sdeleuze sdeleuze self-assigned this Dec 18, 2020
@sdeleuze sdeleuze added in: web Issues in web modules (web, webmvc, webflux, websocket) type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Dec 18, 2020
@quaff
Copy link
Contributor

quaff commented Dec 21, 2020

You could try https://github.com/FasterXML/jackson-modules-base/tree/master/mrbean , It will create an proxy implemented interface.

@sdeleuze
Copy link
Contributor

sdeleuze commented Jan 4, 2021

Good catch, I would expect SerializersKt.serializer(type) provided by kotlinx.serialization to throw an exception in that case, but indeed for some reasons it does not. I have raised that point to the Kotlin team, and will add a related check on Spring side and related tests as well.

@sdeleuze
Copy link
Contributor

sdeleuze commented Jan 4, 2021

I will wait for Kotlin team feedback since the check to use is not obvious because some Java interfaces should be supported (collections) while some others don't.

@tomfi
Copy link

tomfi commented Jan 12, 2021

@scadgek will this solve the problem mentioned in #26321?

In my use-case I have both kotlin serialization and jackson in the classpath, but kotlin serialization was not configured for spring. in previous versions it did not affect anything but since this version spring try to use kotlin serialization in web requests which is not what i expected (or at least i expect to control it somehow)

@sdeleuze
Copy link
Contributor

@tomfi It should for non collection use cases, those who will be fixed via #26371. Please comment here if that's not the case.

@tomfi
Copy link

tomfi commented Jan 12, 2021

@sdeleuze if i understand the fix correctly, it will throw exception in case it fails to find a serializer or it detect a polymorphic use case.

My problem is that first of all, the class that it try to serialzie/deserialize is not even my class, it belongs to spring security (DefaultOAuth2AccessToken).

And i think the root cause is because the change of order. I have both kotlin serialization and jackson in my classpath and now kotlin serialization is picked before jackson (unlike previous version) so it try to serialize/deserialize classes and interfaces with kotlin serialization which caused a regression.

In case is classes that are in my control i would fix it, but for spring security i can't really control it and in general can't really "tell" spring to prefer jackson over kotlin serialization or vice versa.

Hope it clarify a bit.

Edit: if i did not understand it correctly, and somehow it will "know" that the class/interface is not serializable by kotlin serialization and fallback to jackson then it solves my regression.

@sdeleuze
Copy link
Contributor

The exception will be catch on usage side, so in practice if that happens kotlin serialization will be skipped and jackson will be used. The order change has been done on purpose but to work in a reasonable way kotlin serialization should not catch serialization expected to be done by Jackson, hence this issue and #26371 for collections. So yes it should solve your regression if that's not a use case with collections. 5.3.3 has been released so feel free to test and send your feedback.

@tomfi
Copy link

tomfi commented Jan 13, 2021

@sdeleuze sure, thanks for the clarifications 👍

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) type: bug A general bug
Projects
None yet
Development

No branches or pull requests

5 participants