0

I have these Model classes

@Serializable
open class BaseModel(

    var network: String? = null,
    var type: String? = null,

    var createdOn: String? = null,
    var updatedOn: String? = null,

    var name: String? = null,
    var imageUrl: String? = null,
    var description: String? = null,

    var validity: String? = null
)

@Serializable
open class BundleOffer(

    var sms: String? = null,
    var onNet: String? = null,
    var offNet: String? = null,
    var internet: String? = null

    ) : BaseModel()

now these classes define in kotlin-jvm module and i need to create child type for framework-specific use case so i have created test for that like that

    @Serializable
    class BundleOfferChildType(val isFavourite: Boolean = false) : BundleOffer()

    @Test
    fun decodeArrayOfBundleOfferAsChildType() {

        val jsonString = javaClass.classLoader
            .getResourceAsStream("test_bundles_offers_data.json")!!
            .readBytes().toString(Charsets.UTF_8)

        val json = Json {
            encodeDefaults = true
            ignoreUnknownKeys = true
        }

        val result =
            json.decodeFromString(ListSerializer(BundleOfferChildType.serializer()), jsonString)

        assertThat(result.size).isEqualTo(2)
    }

i have test_bundles_offers.json file data as below but there is no createdOn,updatedOn in data and giving MissingFieldException for them but these should be ignored or should be assigned default value as defined in Json configuration

[    
  {
    "network": "...",
    "type": "...",
    "name": "Bundle offer 1",
    "imageUrl": "...",
    "description": "...",
    "validity": "...",
    "sms": "...",
    "offNet": "...",
    "onNet": "...",
    "internet": "..."
   },
     {
    "network": "...",
    "type": "...",
    "name": "Bundle offer 2",
    "imageUrl": "...",
    "description": "...",
    "validity": "...",
    "sms": "...",
    "offNet": "...",
    "onNet": "...",
    "internet": "..."
   }
]
Burhan Khanzada
  • 945
  • 9
  • 27

1 Answers1

0

The problem is related to the fact that BundleOfferChildType class was declared in the test source set, so the plugin-generated serializer is erroneous (specifically, its descriptor; it's implemented as an instance of the internal PluginGeneratedSerialDescriptor class, and for some reason, in this case, its private elementsOptionality field is filled with false values; it would have been correctly filled with true if BundleOfferChildTypeclass was declared in the main source set).

I believe it's a bug of kotlinx.serialization.

As a workaround, just move BundleOfferChildType class from test to the main source set.

  • well main be your right about BundleOfferChildType bee in test source test making this wired behaviour but after your answer i ahve reopen the sample project and just removed BundleOfferChildType and just run that test again and now its showing `BundleOffer` to missing Feilds but i ahve checked its decomplied bytecode and all of that feilds are optional see [this] (https://i.stack.imgur.com/RfbTa.png) – Burhan Khanzada Aug 05 '21 at 01:36
  • now it confirmed that a bug can u file a bug because i don't know if i give that sample to as sample they can reproduce it nor not and i don't have enough knowledge of kotlinx serialization to define that bug properly – Burhan Khanzada Aug 05 '21 at 01:42
  • Try to run the `gradle clean` task before rerunning test. Bug with `BundleOffer` is still reproducible? – Михаил Нафталь Aug 05 '21 at 05:48
  • Looks like this (or a similar one) bug is already reported: https://github.com/Kotlin/kotlinx.serialization/issues/1602 – Михаил Нафталь Aug 05 '21 at 06:05
  • downgrading kotlin version to `1.5.10` does fix wired behaviour that some times its works and some times it doesn't but still if I have `A` serializable class and a `B` class extend from `A` in `main` source and then use it to extend class `C` from `B` in `test` source of in another `module` its till giving error `missing optional field` – Burhan Khanzada Aug 06 '21 at 07:34