Title
j

jonathan

03/10/2018, 8:02 AM
kotlinx.serialization is doing some weird name mangling when stringifying to JSON:
JSON.stringify(UserRegistrationRequest("Jonathan"))
Outputs:
{
  "user_name": "Jonathan",
  "message_name_fojwga$_0": "user_request",
  "SENDER_SIDE_x0f2y$_0": {
    "name$": "CLIENT",
    "ordinal$": 1
  }
}
Where
UserRegistrationRequest
is:
@Serializable
class UserRegistrationRequest(val user_name: String) : SpyfallMessage {
    override val message_name = Companion.message_name // Overrides from interface SpyfallMessage
    override val SENDER_SIDE = Side.CLIENT  // Overrides from interface SpyfallMessage
    companion object {
        const val message_name = "user_request"
    }
}
Context: These exist in a Kotlin Multiplatform Common gradle project and act as messages that are sent between the frontend (Multiplatform JS) and backend (Multiplatform Java) via WebSockets using JSON.
The weird overriding-value (rather than just subclassing an implementation and passing those as constructor parameters) is used because kotlinx.serialization + subclassing doesn't play nicely with JS.
Finally, they're deserialized to an intermediate class (SpyfallMessageImpl) that's just a tiny data class that accepts
message_name
and
SENDER_SIDE
as parameters, which then allows me to further deserialize into the various subclasses manually (it's basically a very long
when
statement), which means that this name mangling causes deserialization to fail.
s

sandwwraith

03/13/2018, 8:27 AM
Looks just a little bug in a plugin, which passes to the runtime mangled names instead of source names. Afaik, names are mangled when they’re overrides or non-public
j

jonathan

03/13/2018, 8:28 AM
Interesting... is there a way to get around this? Or will I just have to remove the overrides and just re-implement
message_name
and
SENDER_SIDE
in every subclass? That latter workaround doesn't feel in the spirit of OOP...
s

sandwwraith

03/13/2018, 8:45 AM
Try to specify
@SerialName
on fields. It will also help you to follow code style conventions for field names
By the way, I can’t reproduce your issue. Do you use plugin
v0.4
and higher?
j

jonathan

03/13/2018, 9:52 AM
Awesome, thanks - I'll try that and get back to you! I'm using 0.4.1. This particular example is serialized from the JS module.
s

sandwwraith

03/13/2018, 9:59 AM
Ah, I’ve solved the case. Serialization works correctly, but you’ve accidentally imported
kotlin.js.JSON
instead
kotlinx.serialization.json.JSON
The former works incorrectly in your case, because it just dumps runtime JS object representation into string
j

jonathan

03/13/2018, 7:08 PM
Oh whoops! That makes total sense. Thank you so much!