Ulrich Schuster
04/30/2024, 10:35 AMBaseContainer
, see example) with a restricted generic type parameter. The generic type itself is a sealed hierarchy (Element
). To my understanding, serializers should be automatically generated for this sealed Element
hierarchy. However, I am not able to use these auto-generated serializers for the parameterized BaseContainer
hierarchy.
// This is the sealed hierarchy, for which serializers should be auto-generated:
@Serializable
sealed interface Element
@Serializable
data class CountElement(val elementCount: Int) : Element
@Serializable
data class FlagElement(val flag: Boolean) : Element
// This is a class hierarchy with generic type parameter E restricted to Element:
@Serializable
sealed interface BaseContainer<out E : Element>
@Serializable
data class ElementContainer<out E : Element>(
val element: E
) : BaseContainer<E>
// This is the serializers module to enable polymorphic serialization of the generic container classes
val containerSerializerModule = SerializersModule {
polymorphic(BaseContainer::class) {
subclass(ElementContainer.serializer(Element.serializer())) // alt: serializer<Element>()
}
// Commented out, so the auto-generated serializers of the sealed Element hierarchy are used.
// polymorphic(Element::class) {
// subclass(FlagElement::class)
// subclass(CountElement::class)
// }
}
// And here is a test to illustrate the problem
internal class GenericSerializerTest {
val json = Json { serializersModule = containerSerializerModule }
@Test
fun `polymorphically serialize and deserialize an element container`() {
val container = ElementContainer(FlagElement(false))
val containerJson = json.encodeToString(serializer<BaseContainer<Element>>(), container)
val containerDeserialized = json.decodeFromString(serializer<BaseContainer<Element>>(), containerJson)
assertEquals(container, containerDeserialized)
}
}
When I run the above test, I get the following error message: kotlinx.serialization.SerializationException: Serializer for subclass 'FlagElement' is not found in the polymorphic scope of 'Element'.
However, when I manually define the polymorphic serializer for the Element
hierarchy (uncomment the lines above), the test passes. Why is that? It seems that the auto-generated serializer is not used when I define the polymorphic serialization for the container. Is this expected? Why?