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

Incorrect serialization of class defined in an external library after upgrade to 0.5.1 #153

Closed
rjaros opened this issue Jun 15, 2018 · 5 comments
Labels
bug compiler-plugin In next release Committed but not published as artifact yet

Comments

@rjaros
Copy link

rjaros commented Jun 15, 2018

When I have @serializable data class defined in an external library:

@serializable
data class LibraryClass(val time: Long)

and I use it in my project (which of course uses the library):

@serializable
data class MyClass(val kdate: LibraryClass)

after serializing:

val x = MyClass(LibraryClass(100))
console.log(JSON.stringify(x))

I get:
{"kdate":"LibraryClass(time=100)"}
instead of:
{"kdate": { "time": 100} }

It worked OK in version 0.5.0 (and Kotlin/JS 1.2.41)

It also works OK if the class is defined in the same project (not in the library).

And also it works correctly if I serialize this class directly:
val x = LibraryClass(100)
console.log(JSON.stringify(x))

{"time": 100}

@Whathecode
Copy link
Contributor

Whathecode commented Jun 15, 2018

Was just about to create what I believe to be the exact same issue. However, I have pinpointed it to any classes defined in an external library. This also does not seem specific to Kotlin/JS, as I am compiling to the JVM. The following unit tests demonstrate this:

class SerializedAsToStringTest
{
    @Serializable
    class Internal

    // The following `External` class is defined in the main sources instead of test sources:
    // @Serializable
    // class External

    @Serializable
    class ExternalNested( val e: External )

    @Serializable
    class InternalNested( val i: Internal )

    @Test
    fun `serializing external class succeeds`()
    {
        val o = External()
        val serialized = JSON.stringify( o )
        assertEquals("{}", serialized )
    }

    @Test
    fun `serializing nested external class succeeds`()
    {
        val o = ExternalNested( External() )
        val serialized = JSON.stringify( o )
        assertEquals( "{\"e\":{}}", serialized ) // Fails, External.ToString() is printed instead.
    }

    @Test
    fun `serializing nested internal class succeeds`()
    {
        val o = InternalNested( Internal() )
        val serialized = JSON.stringify( o )
        assertEquals("{\"i\":{}}", serialized )
    }
}

Could you update the issue title accordingly?

Another interesting finding: open classes serialize correctly. I presume the reason behind this is that open classes are serialized using the PolymorphicSerializer (since extending types need to be supported).

@rjaros rjaros changed the title Incorrect serialization of data class defined in a library after upgrade to 0.5.1 (Kotlin/JS) Incorrect serialization of class defined in an external library after upgrade to 0.5.1 Jun 15, 2018
@Whathecode
Copy link
Contributor

Whathecode commented Jun 19, 2018

A temporary workaround which works is defining the serializer explicitly:

@Serializable
class ExternalNested(
    @Serializable( with = ExternalTestClassSerializer::class )
    val e: ExternalTestClass )

object ExternalTestClassSerializer
    : KSerializer<ExternalTestClass> by ExternalTestClass::class.serializer()

@Whathecode
Copy link
Contributor

I believe the same bug also causes inherited classes from external libraries to be deserialized incorrectly.

In one module define:

@Serializable
abstract class Base
{
    val base: Int = 1
}

In another, define:

@Serializable
data class Extends( val extends: Int = 2 ) : Base()

Serializing this outputs {"extends":2} instead of {"base":1,"extends":2} when they are defined in the same library.

@sandwwraith
Copy link
Member

Fixed with new plugin update

@Whathecode
Copy link
Contributor

Verified. This fixes all issues I reported on here (including the inheritance issue). Thanks for the quick fix!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug compiler-plugin In next release Committed but not published as artifact yet
Projects
None yet
Development

No branches or pull requests

3 participants