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.

Inconsistent behaviour with sealed classes serialization

See original GitHub issue

I faced a problem with sealed classes serialization.

To Reproduce

import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json

@Serializable
sealed class Project {
	abstract val name: String

	@Serializable
	class OwnedProject(override val name: String, val owner: String) : Project()
}

fun main() {
	println(Json.encodeToString(Project.OwnedProject("kotlinx.coroutines", "kotlin")))
	// prints: {"name":"kotlinx.coroutines","owner":"kotlin"}
	val project: Project = Project.OwnedProject("kotlinx.coroutines", "kotlin")
	// prints: {"type":"com.example.Project.OwnedProject","name":"kotlinx.coroutines","owner":"kotlin"}
	println(Json.encodeToString(project))
}

I thought that result in both cases should be equal, but it prints different JSON strings.

Environment

  • Kotlin version: 1.4.10
  • Library version : Kotlinx Serialization Plugin 1.4.10
  • Kotlin platforms: JVM
  • Gradle version: 6.6.1
  • Other relevant context: JRE version: 1.8

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:4
  • Comments:18 (10 by maintainers)

github_iconTop GitHub Comments

1reaction
chipneshcommented, Nov 16, 2020

Is there any way to enable a discriminator field to all class hierarchy forcefully? I mean like JsonTypeInfo annotation for Jackson mapper or something? If I remember correctly Jackson includes a discriminator field in both cases.

My case is related to response serialization in “ktor” route. Because of this problem, it looks like this:

	post("/login") {
		val request = call.receive<LoginCredentials>()
		val response: TokenResponse = authService.login(request)
		call.respond(Json.encodeToString(response))
	}

I have to do manual encoding through encodeToString and have to specify the “needed” response type explicitly.

0reactions
pdvriezecommented, Jan 15, 2021

@joffrey-bion I had been assuming that you were using your own converter. I see that there is an implementation in Spring. Looking at that code: https://github.com/spring-projects/spring-framework/blob/2d53570f4cc148250378b852e671fcb0369f754b/spring-web/src/main/java/org/springframework/http/converter/json/KotlinSerializationJsonHttpMessageConverter.java#L144-L149

it is clear that it does not have an existing mechanism to handle polymorphic types (the code determining the serializer even throws an error). You would have to create your own version (or create a patch/pull request for Spring). The function does have a type parameter in writeInternal (very often null according to references in github), but it is not generally specified. I would say that it would be worthwhile to update the class.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Third-party sealed classes serialization with `kotlinx ... - Medium
All subclasses of a sealed class must be explicitly marked as @Serializable. This is unfortunate because it is impossible to annotate 3rd party ......
Read more >
Obfuscating serializable types generated by the compiler
How compiler-generated serializable classes are generated and how to obfuscate them? The following example shows a simple command-line ...
Read more >
Sealed Classes vs Enum Classes - Dev Genius
Sealed classes in Kotlin are another new concept we didn't have in Java, and open ... The advantage of enum classes is that...
Read more >
Sealed Classes - Oracle Help Center
It is a compile-time error if a class declaration has more than one of the class modifiers sealed , non-sealed and final ....
Read more >
C# XML Serialization Tips - Playground for the mind
At the very least I find it inconsistent as some unassigned values are serialized and some aren't. So to change the behaviour all...
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