https://kotlinlang.org logo
Join SlackCommunities
Powered by
# serialization
  • a

    Alexey Zolotarev

    02/06/2025, 8:42 AM
    Hey folks, is it possible to have value classes serialized/deserialized as primitive values? I'm trying to encode data to CBOR for exchange between Kotlin - TypeScript and I would like to have restricted number types for the data on the Kotlin side so I use value classes. The problem is that default serializer adds class names to the output (a type discriminator) but I would like to use primitive values or maybe custom tags. Is it possible? For example:
    Copy code
    @Serializable
    sealed interface Wrapper
    
    @Serializable
    @JvmInline
    value class StringWrapper(val value: String): Wrapper
    
    @Serializable
    @JvmInline
    value class IntegerWrapper(val value: Int): Wrapper
    
    @Serializable
    @JvmInline
    @OptIn(ExperimentalSerializationApi::class)
    value class BinaryWrapper(@ByteString val value: ByteArray): Wrapper
    
    class DataTreeValueSerializationTest {
        @OptIn(ExperimentalSerializationApi::class, ExperimentalStdlibApi::class)
        @Test
        fun testSerialization() {
            val data = IntegerWrapper(1)
            val serialized = Cbor.encodeToByteArray(Wrapper.serializer(), data)
            println(serialized.toHexString())
            val deserialized = Cbor.decodeFromByteArray(Wrapper.serializer(), serialized)
            assertEquals(data, deserialized)
        }
    }
    This for example is encoded this way:
    Copy code
    Diagnostic:
    [
    	_ "IntegerWrapper",
    	1
    ]
    
    
    Commented:
      9f                -- Array (streaming)
        6e              -- String, length: 14
          496e746567657257726170706572 -- [0], "IntegerWrapper"
        01              -- [1], 1
        ff              -- BREAK
    0x9f6e496e74656765725772617070657201ff
    And I would like to have it
    [1]
    in this case. The interface is sealed and there is only one possible class that corresponds to an integer,
    IntegerWrapper
    so it should be possible to encode/decode it without any ambiguity. With JSON by the way this doesn't work at all since it encodes the data to "1" in this case but then expects an object on deserialization.
    • 1
    • 2
  • g

    Gergely Kőrössy

    02/06/2025, 2:54 PM
    Hey, I need a little help with generics. I've tried searching for a solution but I couldn't find any. I want to encode to / decode from JSON. I have the following class:
    Copy code
    data class Nice<T: @Serializable Any>(
        @SerialName("id") val id: String,
        @SerialName("type") val type: String,
        // ... about 5 more parameters ...
        @SerialName("value") val value: T,
    )
    Based on the
    type
    parameter, the value could be a couple of serializable things: list of a data class(id,name) items, a single data class(id,name) item, or a boolean value. • If I don't set a custom serializer with
    @Serializable(with = ...)
    , the encoding to JSON works, but decoding from JSON runs into
    Star projections in type arguments are not allowed, but had null
    error (trying to decode it as
    Nice<*>
    . • If I set a custom serializer by implementing
    JsonContentPolymorphicSerializer
    I get
    Class 'Nice' is not registered for polymorphic serialization in the scope of 'Nice'.
    even for encoding. Is there any way to tell the deserializer that if the
    type
    value is something, decode
    value
    as either a list / single item / boolean without implementing a full on KSerializer? There are quite a few parameters in the class and would be nice not writing encode / decode statements for each one of them.
    a
    e
    • 3
    • 4
  • o

    Olaf Hoffmann

    02/11/2025, 8:00 AM
    Hey everyone, I was hoping to get some advice with an issue I'm having with
    kotlinx.serialization
    when trying to achieve multiple levels of polymorphism with individual class discriminators for each level. I'm building a library that allows users to deserialize JSON returned from a headless CMS. The CMS supplies a class discriminator for every type returned in its API, but the types themselves are user-defined and may be polymorphic themselves, which is what's causing me trouble. Here's an abstract representation of some JSON that the CMS might return and that library should be able to deserialize.
    Copy code
    [
      {
        "cmsDiscriminator": "someUserType",
        "someUserValue": "value"
      },
      {
        "cmsDiscriminator": "otherUserType",
        "otherUserValue": "value"
      }
    ]
    The library only supplies the base class, setting up the
    cmsDiscriminator
    .
    Copy code
    @Serializable
    @JsonClassDiscriminator("cmsDiscriminator")
    abstract class CmsBase
    Users then extend this base class with their own types which works fine for direct subclasses of
    CmsBase
    .
    Copy code
    @Serializable
    @SerialName("someUserType")
    class SomeUserType(val someUserValue: String) : CmsBase()
    
    @Serializable
    @SerialName("otherUserType")
    class OtherUserType(val otherUserValue: String) : CmsBase()
    The problem arises when the user wants to introduce a new polymorphic hierarchy, where the base class is a subclass of
    CmsBase
    and has its own class discriminator, for JSON like this
    Copy code
    [
      {
        "cmsDiscriminator": "polymorphicUserType",
        "userDiscriminator": "somePolymorphicSubType",
        "someSubValue": "value"
      },
      {
        "cmsDiscriminator": "polymorphicUserType",
        "userDiscriminator": "otherPolymorphicSubType",
        "otherSubValue": "value"
      }
    ]
    The users would have to define a class hierarchy like this:
    Copy code
    @Serializable
    @SerialName("polymorphicUserType")
    @JsonClassDiscriminator("userDiscriminator") // doesn't work
    abstract class UserPolymorphicBase : CmsBase()
    
    @Serializable
    @SerialName("somePolymorphicSubType")
    class SomePolymorphicSubType(val someSubValue: String) : UserPolymorphicBase()
    
    @Serializable
    @SerialName("otherPolymorphicSubType")
    class OtherPolymorphicSubType(val otherSubValue: String) : UserPolymorphicBase()
    However, here's where I'm encountering my first problem: The
    @JsonClassDiscriminator
    annotation can't be used on
    UserPolymorphicBase
    , because the
    Copy code
    Argument values for inheritable serial info annotation 'JsonClassDiscriminator'
    must be the same as the values in parent type 'CmsBase'
    , not allowing us to change the discriminator value for the subclasses of some class in that hierarchy. One way to get around that would be to have the user define and supply a
    JsonContentPolymorphicSerializer
    for their
    UserPolymorphicBase
    class, but I would rather not force that on them. Additionally, it does not save me from the second problem, which is that the library has to define a custom
    SerializerModule
    since the
    CmsBase
    class is not
    sealed
    . In the library, I would have to do something like this
    Copy code
    serializersModule = SerializersModule {
        polymorphic(CmsBase::class) {
            subclass(SomeUserType::class)
            subclass(OtherUserType::class)
            subclass(UserPolymorphicBase::class) // doesn't work
        }
        polymorphic(UserPolymorphicBase::class) {
            subclass(SomePolymorphicSubType::class)
            subclass(OtherPolymorphicSubType::class)
        }
    }
    But that fails because
    UserPolymorphicBase
    is not a concrete class and thus can't be registered as a polymorphic subclass of
    CmsBase
    . This issue gets worse when considering the fact that the polymorphic hierarchy can be nested arbitrarily deep as far as the user is concerned and should accordingly be supported by the library. I believe this should be possible to do with a lot of workarounds, but I was hoping not to have to implement a bunch of custom deserialization logic for this to work. Is there a way to achieve this with what we have available in
    kotlinx.serialization
    ? Thanks in advance for any help and suggestions!
  • d

    David Nault

    02/11/2025, 6:03 PM
    Is there a reason
    serializerOrNull<T>()
    couldn't be implemented as an intrinsic, or otherwise optimized? A bit of performance testing makes me suspect it's doing something expensive, on the order of throwing and catching an exception.
  • h

    HeYiming

    02/17/2025, 2:36 AM
    https://github.com/Kotlin/kotlinx.serialization/issues/2929 [Bug] Inline value class fails to be deserialized from a json string !
  • z

    Zyle Moore

    02/17/2025, 3:48 AM
    There's this comment on the documentation for
    encodeSerializaleValue
    of the Encoder interface > Encodes the value of type T by delegating the encoding process to the given serializer. For example,
    encodeInt
    call is equivalent to delegating integer encoding to Int.Companion.serializer:
    encodeSerializableValue(Int.serializer())
    In the other Encoder examples I've seen, like JSON and Cbor and Protobuf, a different Encoder interface is created, which has different encode methods, like
    encodeTaggedInt
    or
    encodeJsonElement
    . Are these format-specific
    encode*
    methods just strongly-typed convenience methods, preferred over
    encodeSerializableValue
    ? The documentation seems to indicate that even primitives could have an equivalent
    encodeSerializableValue
    call, instead of an interface-specific
    encodeInt
    method. Or at least, their effect on the Encoder should be the same. The first part of the Encoder interface documentation says (my emphasis) > Encoder is a core serialization primitive that encapsulates the knowledge of the underlying format and its storage, exposing only structural methods to the serializer, making it completely format-agnostic. Serialization process transforms a single value into the sequence of its primitive elements, also called its serial form, while encoding transforms these primitive elements into an actual format representation: JSON string, ProtoBuf ByteArray, in-memory map representation etc. Is an
    encodeJsonElement
    really a primitive? Should it be treated as an entrypoint into another serialization (since it should be equivalent to something like
    encodeSerializableValue(JsonElement)
    )? Is an Int as "structural" as a JsonElement?
  • c

    cfleming

    02/18/2025, 9:41 AM
    How does the integration between IntelliJ and Kotlin compiler plugins work? I use a non-standard (well, non-Gradle) build for my Kotlin code, and I get errors all over the place because the IDE can’t resolve the generated
    Type.serializer()
    methods. I have the serialization compiler plugin configured, both in my build and in the Kotlin Compiler settings in the IDE. The code compiles and runs fine both when built in the IDE and when run via the code compiled by my build, but the IDE just isn’t aware that the plugin has been applied. How does this work for Gradle? I had similar problems with Maven, it’s not just really esoteric builds which suffer from this. Is there a way I can configure this?
  • j

    Joshua Hansen

    02/19/2025, 10:59 PM
    Hi. I have an interface which has a
    name
    and a `value`:
    Copy code
    sealed interface MyInterface<T : Any> {
        val name: String
        var value: T
    
    }
    There's a bunch of subclasses which implement this interface with different types:
    Copy code
    class MyClass1(override var value: Boolean) : MyInterface<Boolean> {
        override val name: String = "Foo"
    }
    class MyClass2(override var value: String) : MyInterface<String> {
        override val name: String = "Bar"
    }
    I want to write a custom generic serializer which serializes these classes to/from a string of this format:
    Copy code
    "$name=${/* String Serialized form of value */}"
    I have a list of these in a parent class, like this:
    Copy code
    class Parent {
        val myList: List<MyInterface<*>> = listOf()
    }
    Is it possible to serialize/deserialize
    Parent
    and ensure each member of the list is deserialized into the appropriate class instance? I'm not using JSON format. (I'm using KAML for YAML serialization)
  • r

    Rohde Fischer

    02/20/2025, 1:20 PM
    I want to create an error dto with some kind of classifier of the error in question that can be used for api consumers to consistently handle errors and/or i18n-frameworks to display an appropriate error from experience the amount of errors in a domain tends to increase, so I'm thinking it should be hierarchical, and I also think there's a lot of cases where it would be nice to have a given subdomain shown from the classifier, even though it could be derived from the endpoint giving the error so what I currently imagine is something like
    subdomain.error-group.specific-error
    or similar. This kind of looks like it could be a hierarchy of interfaces and enums, but designing it feels... weird. So I'm wondering, has anyone approached a similar design? How do you use the types and their serialization to achieve this? Is the easiest actually a hierarchy with a single parent requirement? Or is there a better way to do this?
    a
    • 2
    • 1
  • c

    cfleming

    02/24/2025, 7:34 AM
    I'm developing a hierarchy for polymorphic serialization using Kotlin. I have a sealed interface for the polymorphic type, with some concrete cases as data classes identified using @SerialName annotations. I would like to have one of these cases be the default, and in that case the type field should not be serialised, i.e. elements with a null type should be considered to be that default case. Is this possible? I only need JSON serialisation on the JVM.
    • 1
    • 1
  • m

    Matyáš Vítek

    02/24/2025, 4:08 PM
    What would be the best approach to serializing
    Map<Foo, String>
    given that I have a serializer for
    Foo
    ? I really want to avoid writing a serializer for whole
    Map
    class
    e
    • 2
    • 4
  • d

    dawidhyzy

    02/26/2025, 3:01 PM
    I managed to hide it by ignoring a lint rule:
    Copy code
    <lint>
        <issue id="UnsafeOptInUsageError" severity="ignore">
            <option name="opt-in" value="kotlinx.serialization.InternalSerializationApi" />
        </issue>
    </lint>
    👀 1
  • r

    Robert Jaros

    03/02/2025, 7:24 PM
    What could this mean?
    Copy code
    throwLinkageError("Function 'encodeToString' can not be called: No function found for symbol 'kotlinx.serialization.json/Json.encodeToString|encodeToString(0:0){0\xA7<kotlin.Any?>}[0]'");
    I'm getting this when upgrading a Kotlin/JS project to Kotlin 2.1.20-RC.
    a
    s
    • 3
    • 17
  • j

    James

    03/05/2025, 12:46 PM
    I have a problem where I have this Health data class that has a generic type parameter.
    T
    can either be
    Nothing
    or something user-defined (that also has a
    @Serializable
    annotation). Whenever I try to serialize it I get an error:
    Copy code
    kotlinx.serialization.SerializationException: Serializer for class 'Health' is not found.
    Please ensure that class is marked as '@Serializable' and that the serialization compiler plugin is applied.
    All my data classes are defined with Serializable, so I'm unsure of how to go forward with this. I was thinking about writing a custom serializer that implements KSerializer. But I'm not entirely sure where to start as I haven't really looked into writing serializers before. I want to avoid doing anything JSON specific, as the type should work for other formats than JSON as well. Any advice appreciated.
    Health.kt
  • m

    Mehmet

    03/07/2025, 9:11 AM
    Is it possible to globally override the built-in serializer for a primitive type, such as
    Boolean
    , without requiring explicit
    @Contextual
    annotations on every field?
    e
    r
    • 3
    • 7
  • c

    Charann

    03/10/2025, 5:26 AM
    In the below case, I expected the serializer to de-code the scientific notation and consider it is as a "long"
    Copy code
    fun testSerializer(){
        val str = """{"doubleVal":1.725255546765E12}"""
        val json = Json {
            isLenient = true
        }
        val obj = json.decodeFromString<DoubleVal>(str)
        println(obj)
    }
    @Serializable
    class DoubleVal(val doubleVal: Long)
    But I got an error "Unexpected JSON token at offset 13: Unexpected symbol '.' in numeric literal at path: $.doubleVal" I tried using flags like "isLenient" but of no use. Am I missing any flags?
    a
    • 2
    • 1
  • k

    krzysztof

    03/13/2025, 9:16 AM
    I’m using kotlin 2.1.0, with json serialization version 1.8.0. For my data class using Uuid, the compiler gradle plugin says
    serializer has not been found for type 'Uuid'
    , but there is one built-in from serialization lib itself - how to properly mark Uuid as serializable?
    h
    • 2
    • 1
  • j

    J

    03/18/2025, 8:01 AM
    I've been trying to write a "SafeSerializer", a custom serializer that allows me to return null when the serialization of an object fails, however I feel my knowledge of serialization is lacking and I can't seem to get it to work. Has anyone done something similar, or has any idea how it would look?
    e
    • 2
    • 4
  • z

    Zyle Moore

    04/01/2025, 12:19 AM
    I have a
    @SerialInfo
    annotation that indicates that the property is tagged with the given name,
    @Field("HEDR")
    . When a property has this annotation, it is encoded as a Type-Length-Value structure. As an example,
    Copy code
    @Field("HEDR")
    val header: String = "asdf"
    Results in bytes matching
    TT TT TT TT LL LL VV VV VV VV
    (
    HEDR 04 00 asdf
    ) But, to get this to happen, I have to override the
    decode*Element
    method for each primitive, to support each serializable type. Example,
    Copy code
    @Field("HEDR")
    val header: String = "asdf"
    
    @Field("INTV")
    val taggedValues: Int = 1
    Is there an easy/cheap way to perform this tagging on any type, without overriding that specific type in the codec?
    • 1
    • 1
  • c

    CLOVIS

    04/03/2025, 11:41 AM
    I have some multiplatform code that generates JSON. However, sometimes, the JSON is slightly different in ways that doesn't matter (e.g. one system writes
    1
    and another writes
    1.0
    ). Could KotlinX.Serialization be used to deserialize multiple JSON representations and tell me if they are equal or not?
    e
    s
    • 3
    • 4
  • h

    hellman

    04/04/2025, 7:10 AM
    Hi! I have a data class with a couple of properties that should be marked
    @Transient
    and they are calculated in the init block, but that doesn't seem to be allowed. It works if I change it to a
    lateinit var
    but that seems wrong. Is this a bug in kotlinx-serialization or is there a workaround?
    c
    h
    +2
    • 5
    • 17
  • s

    Smoothie

    04/07/2025, 1:50 PM
    Hey as duplicate of #C3SGXARS6 question When I try to pass a (kotlinx serializer) JsonObject to a Kotlin listener that is used in a Swift app, that contain a JsonArray I get the error "Could not cast value of type `KListAsNSArray' to "Kotlinx_serialization_jsonJsonElement', there seem to be an issue in interop of kotlinx.serializer ? Anyone else can reproduce this issue ?
  • l

    Lukasz Kalnik

    04/07/2025, 2:55 PM
    I have to deserialize JSON, where a field can be any JSON primitive (e.g. null, int, string, double, boolean). Can I just define it in my data model as
    JsonPrimitive
    and it will work out-of-the-box?
    Copy code
    @Serializable
    data class Response(
        val field: JsonPrimitive
    )
    h
    t
    • 3
    • 19
  • e

    Emil Kantis

    04/08/2025, 9:43 AM
    Using JSON, is there any way to deserialize only keys of an object into a list? i.e
    Copy code
    {
      "foo": { // irrelevant },
      "bar": { // irrelevant },
    } -> // [ "foo", "bar ]
    Currently I got a
    Copy code
    data class Wrapper(
      val entries: Map<String, Irrelevant>
    )
    But I would like to discard/ignore the values of the map
    n
    e
    • 3
    • 14
  • n

    Nikky

    04/11/2025, 7:22 AM
    so.. xn32/Json5k has been archived a while ago (and i just noticed).. does anyone know of a good json5 lib for serialization? this is for config files with comments and such
    h
    • 2
    • 3
  • a

    Andrey Tabakov

    04/21/2025, 1:13 PM
    What do you think about this? https://github.com/Kotlin/kotlinx.serialization/issues/2993
    a
    • 2
    • 2
  • r

    rocketraman

    04/25/2025, 1:37 PM
    I am experimenting with implementing "typed ids" similar to those used by Stripe. See article https://dev.to/stripe/designing-apis-for-humans-object-ids-3o5a. I've played around with various implementations but nothing comes out very clean and elegant on both the data model side and the kotlinx-serialization side. Anyone have any thoughts / design ideas? Ideally I'd like to have the serializable class be as simple as
    data class FooBar(val id: TypedUuid<FooBar>, …)
    and the serialization of
    id
    be as simple as
    fb_<uuid>
    .
    p
    • 2
    • 4
  • m

    Marcello Galhardo

    04/28/2025, 8:29 PM
    Since there’s a reified
    serializer<T>()
    that throws if no serializer is found, why isn’t there a
    serializerOrNull<T>()
    as well? I know there’s a
    serializerOrNull(KType)
    , but as I understand it,
    typeOf<T>()
    relies on reflection and has performance implications.
    e
    • 2
    • 4
  • s

    S.

    05/01/2025, 10:27 AM
    I need a
    JsonObject
    to specify response formats of a third party lib, is it somehow possible to retrieve a JsonObject from a
    @Serializable class MyClass
    without writing the mapping by hand?
    g
    • 2
    • 2
  • z

    Zyle Moore

    05/11/2025, 3:02 AM
    Is there some type to represent anything that's Serializable? For context, this isn't about an existing format like Json or Cbor. I'm trying to make a generic wrapper, but keep ending up at making the type
    Any
    and getting an error that no serializer for
    Any
    was found. I understand why, I'm just not quite sure how to get what I want with that being true. By default, something like
    @Serializable data class Point(val x: Int, val y: Int)
    will eventually make a call to
    beginStructure
    , two calls to
    encodeInt
    , and a call to
    endStructure
    . If I replace
    Int
    with any other primitive type, like
    Short
    ,
    Double
    ,
    Float
    ,
    Long
    , the two calls in the middle will be the appropriate method for that type,
    encodeShort
    ,
    encodeFloat
    , etc. I'm looking for something that behaves exactly the same way, but the encode method it calls is
    encodeSerializableValue
    instead of
    encodeInt
    . Or maybe even
    encodeInline
    . This example though doesn't use generics, so perhaps it's easier for the generator to map confidently. In my generic wrapper example, I have a
    @Serializable @JvmInline value class FieldValue<T : Any>(val value: T) : FieldToken
    The idea being a very thin wrapper around some serializable value, that I can treat as a subtype of
    FieldToken
    . I have a containing class
    @Serializable data class Record(val header: RecordHeader, val fields: List<FieldValue<Any>>)
    which is where my trouble comes in. I want to be able to serialize, roughly, something that looks like
    Copy code
    [ "TES4", [ flags, formId, timestamp, versionControl, recordVersion, unknown ] ],// RecordHeader
      [ "HEDR", [ 1.7, 0, 0 ] ],// // FieldValue<(Float, Short, Short)>
      [ "CNAM", "Zymus" ],// FieldValue<NullTerminatedString>
      [ "SNAM", "TES4 JSON Tuple Example" ],// FieldValue<NullTerminatedString>
      [ "MAST", "Skyrim.esm" ],// FieldValue<NullterminatedString>
      [ "DATA", 0 ],// FieldValue<Long>
      [ "MAST", "Update.esm" ],// FieldValue<NullTerminatedString>
      [ "DATA", 0 ],// FieldValue<Long>
      [ "MAST", "Hearthfires.esm" ],// FieldValue<NullTerminatedString>
      [ "DATA", 0 ],// FieldValue<Long>
      [ "ONAM", [ 0 ] ],// FieldValue<List<Int>>
      [ "INTV", 0 ],// FieldValue<Int>
      [ "INCC", 0 ]// FieldValue<Short>
    c
    • 2
    • 2