Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deserialization of classes with value classes as parameters and default values fails #691

Closed
FWest98 opened this issue Aug 2, 2023 · 1 comment
Labels

Comments

@FWest98
Copy link

FWest98 commented Aug 2, 2023

Describe the bug
When trying to deserialize a class that has a constructor with both a value class instance, as well as a non-nullable property with a default value, Jackson won't find the correct constructor and resort to passing null to the non-nullable property.

To Reproduce

@JvmInline
value class Bar (val bar: Int)

class Foo (
    val bar: Bar,

    @JsonIgnore
    val nonNullDefault: String = "",
)

As is probably known to you, Kotlin will generate a synthetic constructor with extra int, DefaultConstructorMarker parameters to deal with default values, besides the "normal" constructor with all parameters. However, in the specific case that one of the values is also a value class, there is no such "normal" constructor, and it too will have an additional DefaultConstructorMarker. We can see this by listing the constructors for Foo:

public nl.test.Foo(int,java.lang.String,kotlin.jvm.internal.DefaultConstructorMarker)
public nl.test.Foo(int,java.lang.String,int,kotlin.jvm.internal.DefaultConstructorMarker)

Consequently, the Constructor<T>.kotlinFunction call at ReflectionCache.kotlinFromJava returns null, since none of these constructors have a Kotlin function. As a consequence of that, the KotlinValueInstantiator will resort to the normal Java behaviour, calling a default Java constructor with a null value for the nonNullDefault property, resulting in a runtime error/NPE.

Expected behavior
I would expect parsing to succeed, obviously. However, I don't know how best to mitigate the cause of this issue.

Versions
Kotlin: 1.8.21
Jackson-module-kotlin: 2.15.2
Jackson-databind: 2.15.2

This is probably sideways related to #650

@FWest98 FWest98 added the bug label Aug 2, 2023
@k163377
Copy link
Contributor

k163377 commented Aug 4, 2023

As explicitly stated in #650, jackson-module-kotlin does not currently support deserialization of value class.
If you want to try deserialization of value class, please use Kogera.
#650

Also note that annotations on the parameters of constructors that contain value class as a parameter will not work.
https://github.com/ProjectMapK/jackson-module-kogera/blob/5637993d70c71db8581d6db75647cfaaafa20425/src/main/kotlin/io/github/projectmapk/jackson/module/kogera/KotlinFeature.kt#L60-L76

As a side note, both Kogera and kotlin-reflect have a known edge case error when using value class in combination with default arguments.
ProjectMapK/jackson-module-kogera#51
https://youtrack.jetbrains.com/issue/KT-57357

All the information you have reported appears to be a known problem, so I am closing it.

@k163377 k163377 closed this as completed Aug 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants