n

    nschulzke

    1 year ago
    I have an interface for Events that has multiple concrete sealed class implementations, like so:
    // in package com.example.platform
    interface Event
    
    // in package com.example.customer
    @Serializable
    sealed class CustomerEvent : Event {
        object CustomerEvent1
        ...
    }
    
    // in package com.example.supplier
    @Serializable
    sealed class SupplierEvent : Event {
        object SupplierEvent1
        ...
    }
    I would like to be able to serialize/deserialize
    Event
    , but I don't really want to have all the event trees in one package, so using one big
    sealed class
    hierarchy doesn't work well. Does anyone have any idea how to go about registering
    Event
    as polymorphically serializable?
    I tried registering
    Event
    as polymorphic:
    SerializersModule {
        polymorphic(Event::class) {
            subclass(CustomerEvent::class, CustomerEvent.serializer())
            subclass(SupplierEvent::class, SupplierEvent.serializer())
        }
    }
    But I get this error:
    Serializer for Event can't be registered as a subclass for polymorphic serialization because its kind SEALED is not concrete. To work with multiple hierarchies, register it as a base class.
    What does work is adding each concrete class to the
    polymorphic
    block, but there are dozens of them and that's liable to get forgotten over time as we add more.
    Fudge

    Fudge

    1 year ago
    'register it as a baseclass', there might be something akin to baseclass() you can use instead of subclass()
    Or maybe do polymorphic() instead of subclass()
    Also try subclass(CustomEvent.serializer())
    Dominaezzz

    Dominaezzz

    1 year ago
    Register the concrete classes not the sealed class. (or you can do
    polymorphic
    for each subclass, as Fudge says)
    e

    ephemient

    1 year ago
    register them all as polymorphic, if you're worried about missing one then add a test which can reflectively check all subclasses
    n

    nschulzke

    1 year ago
    K, I was afraid that was the answer. Thanks.
    e

    ephemient

    1 year ago
    well, if you want to live dangerously, you could always to the sketchy reflection stuff in production
    I recommend against it, though
    one thing you can do is have a SerializersModule per package, and just
    +
    them all together; that way the various
    polymorphic(...)
    registrations are closer to the declarations, e.g.
    // in package com.example.customer
    val serializersModule = SerializersModule {
        polymorphic(Event::class, CustomerEvent.CustomerEvent1::class, CustomerEvent.CustomerEvent1.serializer())
    }
    
    // in package com.example.supplier
    val serializersModule = SerializersModule {
        polymorphic(Event::class, SupplierEvent.SupplierEvent1::class, SupplierEvent.SupplierEvent1.serializer())
    }
    
    // at serialization usage site
    val json = Json {
        serializersModule = com.example.customer.serializersModule + com.example.supplier.serializersModule
    }