kotlinx.serialization is doing some weird name man...
# serialization
j
kotlinx.serialization is doing some weird name mangling when stringifying to JSON:
JSON.stringify(UserRegistrationRequest("Jonathan"))
Outputs:
Copy code
{
  "user_name": "Jonathan",
  "message_name_fojwga$_0": "user_request",
  "SENDER_SIDE_x0f2y$_0": {
    "name$": "CLIENT",
    "ordinal$": 1
  }
}
Where
UserRegistrationRequest
is:
Copy code
@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
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
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
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
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
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
Oh whoops! That makes total sense. Thank you so much!