kotlinx.serialization
kotlinx.serialization copied to clipboard
Polymorphic SerializersModule with generic class "Star projections in type arguments are not allowed"
Consider this code:
val responseModule = SerializersModule {
polymorphic(Response::class) {
subclass(OkResponse::class)
}
}
@Serializable
abstract class Response<out T>
@Serializable
class OkResponse<out T>(val data: T) : Response<T>()
Running it produces:
Caused by: java.lang.IllegalArgumentException: Star projections in type arguments are not allowed, but had example.examplePoly17.OkResponse<*> (Kotlin reflection is not available)
Is there a workaround for this issue? Using Any instead of * gives me Serializer for class 'Any' is not found
Any new info on this?
Same error
GMT+8, 2021-03-21 01:50:06 , Use the latest version or the same error.
Not sure this is related, but I had the same error.
I found the following workaround: in my case, there was an interface constraint on the generic, and I could register the subclass as follows causing the error to disappear:
subclass(
OkResponse::class,
OkResponse.serializer( PolymorphicSerializer( InterfaceConstraint::class ) )
as KSerializer<OkResponse<*>>
)
I can't serialize an open type hierarchy with a type parameter on the base class due to this issue, and I can't serialize a closed type hierarchy with a type parameter on the base class due to https://github.com/Kotlin/kotlinx.serialization/issues/1784. The only workaround I've found so far is to remove the generic entirely, which sucks.
Any news folks?
Nope
Any good solutions yet?
@ForteScarlet You can specify serializer with a fixed T: subclass(OkResponse.serializer(SomeTSerializer))
You can specify serializer with a fixed
T:subclass(OkResponse.serializer(SomeTSerializer))
Is there a way to make it work for polymorphicDefaultSerializer(Foo::class) { serializersModule.serializer() }?
The serializer is registered as contextual.
@SettingDust It can't really work without providing a concrete serializer. What happens is that the type parameter is actually resolved to a serializer, but, unsurprisingly, there is no serializer for *. Another consideration is that generic type parameters are erased at runtime, so there is no way to determine the "right" (de)serializer either. As such the only way is to either specify a member serializer or to have a serializer that itself can work out what to do with the member based upon the data/contents.