Skip to content

[v0.90.3] List<@Polymorphic Any> doesn't support defaultDeserializer #256

@AdrienDaily

Description

@AdrienDaily

Hello,

I'm having trouble to have a fallback on a List<@polymorphic Any> with optional children (non handled atm).

Given this example XML:

<Extensions>
    <Extension source="mySource">
        <![CDATA[{"savedData":""}]]>
    </Extension>
    <Extension type="AdVerifications">
        <AdVerifications>
            <Verification vendor="Something">
                <JavaScriptResource apiFramework="omid" browserOptional="true">
                    <![CDATA[https://google.com/video.js]]>
                </JavaScriptResource>
                <VerificationParameters>
                    <![CDATA[{"key":"21649"}]]>
                </VerificationParameters>
            </Verification>
        </AdVerifications>
    </Extension>
    <Extension type="geo">
        <Country>IE</Country>
        <Bandwidth>4</Bandwidth>
    </Extension>
</Extensions>

I'm trying to solve it like this:

 @Serializable
@SerialName("Extension")
data class ExtensionDto(
    val source: String? = null,
    val type: String? = null,
    @XmlValue
    var value: List<@Polymorphic Any> = listOf()
) {
    companion object {
        fun module() = SerializersModule {
            polymorphic(Any::class) {
                defaultDeserializer { Unknown.serializer() }
                subclass(String::class)
                subclass(AdVerificationsDto::class)
            }
        }
    }
}

@Serializable
class Unknown

I also tried using:

fun module() = SerializersModule {
    polymorphicDefaultDeserializer(Any::class) { UnknownType.serializer() }
    polymorphic(Any::class) {
        subclass(AdVerificationsDto::class)
        subclass(String::class)
    }
}

And the parser setup:

object XmlParser {
     @OptIn(ExperimentalXmlUtilApi::class)
    val parser = XML(ExtensionDto.module()) {
        policy = DefaultXmlSerializationPolicy(formatCache = defaultSharedFormatCache()) {
            autoPolymorphic = true
            unknownChildHandler = UnknownChildHandler { _, _, _, _, _ -> emptyList() }
        }
    }
}

I also tried using a wrapper but couldn't solve the issue with the string type as I can't use it as a subclass of a specific wrapper type.

The error I get when trying to parse this country field (that we don't handle ATM so just returning null or an empty class like the Unknown one would be fine)

The unknownChildHandler seems to not be used as a fallback either.
I tried removing the default serializer without success.

 error (exception=nl.adaptivity.xmlutil.serialization.XmlParsingException: Invalid XML value at position: 137:23: No XmlSerializable found to handle unrecognized value tag Country in polymorphic context)
                                    nl.adaptivity.xmlutil.serialization.XmlParsingException: Invalid XML value at position: 137:23: No XmlSerializable found to handle unrecognized value tag Country in polymorphic context
                                    	at nl.adaptivity.xmlutil.serialization.XmlDecoderBase.deserializeSafe(XMLDecoder.kt:2229)
                                    	at nl.adaptivity.xmlutil.serialization.XmlDecoderBase$AnonymousListDecoder.decodeSerializableElement(XMLDecoder.kt:1701)
                                    	at kotlinx.serialization.encoding.CompositeDecoder$DefaultImpls.decodeSerializableElement$default(Decoding.kt:538)
                                    	at kotlinx.serialization.internal.CollectionLikeSerializer.readElement(CollectionSerializers.kt:80)
                                    	at kotlinx.serialization.internal.AbstractCollectionSerializer.readElement$default(CollectionSerializers.kt:51)
                                    	at kotlinx.serialization.internal.AbstractCollectionSerializer.merge(CollectionSerializers.kt:36)
                                    	at nl.adaptivity.xmlutil.serialization.XmlDecoderBase$TagDecoderBase.decodeSerializableElement(XMLDecoder.kt:900)
                                    	at com.dailymotion.adsharedsdk.feature.vastparser.data.dto.ExtensionDto$$serializer.deserialize(VastDto.kt:168)
                                    	at com.dailymotion.adsharedsdk.feature.vastparser.data.dto.ExtensionDto$$serializer.deserialize(VastDto.kt:168)
                                    	at nl.adaptivity.xmlutil.serialization.XmlDecoderBase.deserializeSafe(XMLDecoder.kt:111)
                                    	at nl.adaptivity.xmlutil.serialization.XmlDecoderBase$AnonymousListDecoder.decodeSerializableElement(XMLDecoder.kt:1701)
                                    	at kotlinx.serialization.encoding.CompositeDecoder$DefaultImpls.decodeSerializableElement$default(Decoding.kt:538)
                                    	at kotlinx.serialization.internal.CollectionLikeSerializer.readElement(CollectionSerializers.kt:80)
                                    	at kotlinx.serialization.internal.AbstractCollectionSerializer.readElement$default(CollectionSerializers.kt:51)
                                    	at kotlinx.serialization.internal.AbstractCollectionSerializer.merge(CollectionSerializers.kt:36)
                                    	at nl.adaptivity.xmlutil.serialization.XmlDecoderBase$TagDecoderBase.decodeNullableSerializableElement(XMLDecoder.kt:976)

Thanks again for your help !

Metadata

Metadata

Assignees

No one assigned

    Labels

    indevThe issue is fixed/implemented in the dev branch

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions