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

@JsonProperty ignored when serialising Kotlin @JvmRecord in 2.16.X #773

Open
3 tasks done
bmorris591 opened this issue Mar 2, 2024 · 3 comments
Open
3 tasks done
Labels

Comments

@bmorris591
Copy link

bmorris591 commented Mar 2, 2024

Search before asking

  • I searched in the issues and found nothing similar.
  • I searched in the issues of databind and other modules used and found nothing similar.
  • I have confirmed that the problem only occurs when using Kotlin.

Describe the bug

When serialising the following Kotlin data class with 2.16.1 I get the wrong properties generate. This works with 2.15.4.

@JvmRecord
data class JacksonTest(
    @JsonProperty("propertyOne")
    val one: String,
    @JsonProperty("propertyTwo")
    val two: String
)

The following simple test code

fun main() {
    val mapper = JsonMapper.builder().findAndAddModules()
        .build()
        .enable(INCLUDE_SOURCE_IN_LOCATION)

    val test = JacksonTest("one", "two")
    val ser = mapper.writeValueAsString(test)
    println(ser)
    val de = mapper.readValue<JacksonTest>(ser)
    println(de)
}

Produces the following error

Exception in thread "main" com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException: Instantiation of [simple type, class uk.co.borismorris.JacksonTest] value failed for JSON property propertyOne due to missing (therefore NULL) value for creator parameter one which is a non-nullable type
 at [Source: (String)"{"one":"one","two":"two"}"; line: 1, column: 25] (through reference chain: uk.co.borismorris.JacksonTest["propertyOne"])
	at com.fasterxml.jackson.module.kotlin.KotlinValueInstantiator.createFromObjectWith(KotlinValueInstantiator.kt:101)
	at com.fasterxml.jackson.databind.deser.impl.PropertyBasedCreator.build(PropertyBasedCreator.java:202)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:526)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1493)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:348)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:185)
	at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:342)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4899)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3846)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3829)
	at uk.co.borismorris.JacksonTestKt.main(JacksonTest.kt:30)
	at uk.co.borismorris.JacksonTestKt.main(JacksonTest.kt)

As you can see, the property is called one etc, not propertyOne.


Removing @JvmRecord causes the test to pass. This works correctly with @JvmRecord in 2.15.4.


Versions

Java: GraalVM CE 21.0.2+13.1 (build 21.0.2+13-jvmci-23.1-b30)
Kotlin: 1.9.22 (jvmTarget 21)
Jackson BOM: 2.16.1

To Reproduce

fun main() {
    val mapper = JsonMapper.builder().findAndAddModules()
        .build()
        .enable(INCLUDE_SOURCE_IN_LOCATION)

    val test = JacksonTest("one", "two")
    val ser = mapper.writeValueAsString(test)
    println(ser)
    val de = mapper.readValue<JacksonTest>(ser)
    println(de)
}

@JvmRecord
data class JacksonTest(
    @JsonProperty("propertyOne")
    val one: String,
    @JsonProperty("propertyTwo")
    val two: String
)

The above runs correctly if

  • I remove @JvmRecord
  • I downgrade Jackson BOM to 2.15.4

Expected behavior

No response

Versions

Java: GraalVM CE 21.0.2+13.1 (build 21.0.2+13-jvmci-23.1-b30)
Kotlin: 1.9.22
Jackson-module-kotlin: 2.16.1
Jackson-databind: 2.16.1
Jackson-bom: 2.16.1

Additional context

Discovered when investigating Spring Boot 3.3.X

@k163377
Copy link
Contributor

k163377 commented May 4, 2024

This seems to occur without registering a KotlinModule.

In the case of the code you submitted, the annotation is given as a constructor parameter.
At this time, databind seems to ignore this annotation.
For example, this problem can be avoided by specifying @field:JsonProperty.

I have submitted an issue to jackson-databind regarding this behavior.
I'll see what functionality kotlin-module should provide later.
FasterXML/jackson-databind#4513

@bmorris591
Copy link
Author

Just tracking this round the houses - it seems to have ended up as a Kotlin bug https://youtrack.jetbrains.com/issue/KT-67977

@cowtowncoder
Copy link
Member

Some other context: Jackson 2.18 will finally get Property Introspection rewrite -- FasterXML/jackson-databind#4515 -- completion of which should make it possible to address some problems that formerly could not, wrt Kotlin introspection.
Not sure if it could help here but might well do so.

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

3 participants