kotlinx.serialization: Serializing generics is not working
Serializing the following Container<Data> class fails with:
INSTANCE
java.lang.NoSuchFieldException: INSTANCE
@Serializable
class Container<T>(val data: T)
@Serializable
class Data(val text: String)
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 15 (7 by maintainers)
If you have non-generic class (say,
MyData(val a: Container<Data>), you can use simpleMyData.serializer(). However, if your class has type arguments, you have to provide serializers explicitly for each generic type.In some observable future, we are going to invent mechanism such compiler could also insert serializers on call-site, not only in internal serialization calls. This should make things easier.
Error seems like you’re trying to serialize container by simple
JSON.stringify(Container(Data(..))). Because of generic type erasure, this wouldn’t work: On runtime, framework can’t determine how to serialize data in container. ThusContainerclass does not have default (object) serializer, and thus there is no fieldINSTANCE.Right way to do it is to create serializer explicitly:
JSON.stringify(Container.serializer(Data.serializer()), Container(Data(...)))You can learn more here
PolymorphicSerializer has no state so is threadsafe, but the generated serializers for classes have no specific thread support. That is, if you change the object while it is being serialized this will likely lead to incorrect values. Custom serializer code can of course add locks where appropriate or be externally synchronized.
Remember there are two kinds of “serializers” there is the code specific to types (which includes PolymorphicSerializer) and the output/input such as JSON. The JSON class has state and no synchronization so isn’t threadsafe, the serializers providing the information to json themselves have the limited threadsafety I described above…
JSON.parsealso requires explicit serializer in your case - generic arguments are not reified, even if the function reified itself 😦 So in your case you should end with something likeYes, for now IDEA experience is slightly poor because it don’t recognize some synthetic functions. You can improve it by following this instructions: https://github.com/Kotlin/kotlinx.serialization#working-in-intellij-idea
Ok thanks, I tried it (see below) but it still fails with the same error. What am I doing wrong? I’m using version 0.3.
Btw. IDEA is not recognising
Container.serializerbut onlyContainer::class.serializer. However, if I use the later I can’t doContainer::class.serializer(Data::class.serializer())Why is that?