Skip to content

[Bug] A data class that has an inline class-typed property can't be deserializedΒ #413

Closed
@izstas

Description

@izstas

Describe the bug
A data class that has an inline class-typed property can't be deserialized.

To Reproduce
Run:

import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue

inline class MyInlineClass(val i: Int)

data class MyDataClass(val i: MyInlineClass)

fun main() {
    val mapper = jacksonObjectMapper()
    val json = mapper.writeValueAsString(MyDataClass(MyInlineClass(1)))
    println(json)
    val deserialized = mapper.readValue<MyDataClass>(json)
    println(deserialized)
}

Expected behavior
The JSON is properly deserialized.

Actual behavior

{"i":1}
Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `MyDataClass` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (String)"{"i":1}"; line: 1, column: 2]

Or, if there are multiple fields in the data class:

{"i":1,"j":1}
Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `MyDataClass` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (String)"{"i":1,"j":1}"; line: 1, column: 2]

Versions
Kotlin: 1.4.21
Jackson-module-kotlin: 2.12.1
Jackson-databind: 2.12.1

Additional context
I've tried to dig through this and discovered that adding an inline class-typed property causes some constructor changes - the compiled data class has two constructors:

  // access flags 0x2
  private <init>(I)V

  // access flags 0x1001
  public synthetic <init>(ILkotlin/jvm/internal/DefaultConstructorMarker;)V

The second one is ignored by Jackson because it's synthetic. The first one is correctly discovered, however, that constructor is invisible through Kotlin reflection, so Jackson-module-kotlin fails to discover the parameter names and is not able to use that constructor.

The problem can not be worked around by using @JsonProperty because Kotlin compiler places it onto the parameters of the synthetic constructor, and no annotations appear on the private constructor.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions