Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deserialization issues with 0.90.2+ #254

Open
hrkfdn opened this issue Nov 19, 2024 · 4 comments
Open

Deserialization issues with 0.90.2+ #254

hrkfdn opened this issue Nov 19, 2024 · 4 comments
Labels
cantfix This issue cannot be resolved at this point because of limitations in external libraries.

Comments

@hrkfdn
Copy link

hrkfdn commented Nov 19, 2024

This problem occurs with 0.90.2 and 0.90.3. See the following example:

class Test {
    @Serializable
    @SerialName("element")
    data class Element(
        @XmlElement(true)
        val a: String
    )

    @Serializable
    @SerialName("element")
    data class OtherElement(
        @XmlElement(true)
        val b: String
    )

    @Serializable
    data class Parent(
        val element: Element,
    )

    @Serializable
    data class OtherParent(
        val element: OtherElement,
    )

    @Serializable
    data class Root(
        val parent: Parent,
        val otherParent: OtherParent,
    )

    @Test
    fun `xml version 0_9_x test`() {
        val xml = XML {
            indent = 4
        }

        val root = Root(
            parent = Parent(Element("element")),
            otherParent = OtherParent(OtherElement("element")),
        )
        val serialized = xml.encodeToString(root)
        println(serialized)
        val deserialized: Root = XML.decodeFromString(serialized)

        assertEquals(root, deserialized)
    }
}

This will print the following XML:

<Root>
    <Parent>
        <element>
            <a>element</a>
        </element>
    </Parent>
    <OtherParent>
        <element>
            <a>element</a>
        </element>
    </OtherParent>
</Root>

Note how in OtherParent/element the tag is <a>, even though it should be <b>.

@pdvrieze
Copy link
Owner

I've confirmed the issue. It is a caching issue. To get it to work you can disable the cache using (or with whatever policy configuration you use):

XML {
  indent = 4
  defaultPolicy {
      formatCache = FormatCache.Dummy
  }
}

@pdvrieze
Copy link
Owner

pdvrieze commented Nov 19, 2024

I've analysed it. And the key reason is that Element and OtherElement have the same serial name, and as such their types can not be distinguished (and their descriptors are effectively identical). If you instead use @XmlSerialName it will work correctly as that annotation is not transparent.
Note that this is a fundamental limitation of the serialization library. Looking at the implementation of PluginGeneratedSerialDescriptor (and the debugger) the serialDescriptors of both are equal (despite the element names being different).

pdvrieze added a commit to pdvrieze/kotlinx.serialization that referenced this issue Nov 19, 2024
…use side) element names, rather than only the serial names of the element types. This fixes pdvrieze/xmlutil#254.
@pdvrieze pdvrieze added the cantfix This issue cannot be resolved at this point because of limitations in external libraries. label Nov 19, 2024
@pdvrieze
Copy link
Owner

This needs "fixing" in the serialization library itself. In the meantime consider that having two types with equal @SerialName annotation in the same serialization context is not supported.

pdvrieze added a commit that referenced this issue Nov 19, 2024
underlying library (a pull request has been submitted: Kotlin/kotlinx.serialization#2862) for a fix. In the meantime either disabling the
cache or using `@XmlSerialName` instead of `@SerialName` will fix it.
@hrkfdn
Copy link
Author

hrkfdn commented Nov 19, 2024

Makes sense, thanks for investigating!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cantfix This issue cannot be resolved at this point because of limitations in external libraries.
Projects
None yet
Development

No branches or pull requests

2 participants