From cf7a44d2992faa155375c400346d4007a6cce981 Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sun, 2 Feb 2025 13:45:24 +0900 Subject: [PATCH 1/3] Fixed handling of null and JsonValue as well as #904 --- .../module/kotlin/KotlinSerializers.kt | 6 ++-- .../module/kotlin/test/github/GitHub873.kt | 31 ++++++++++++++----- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinSerializers.kt b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinSerializers.kt index efffdd6a..32d90c62 100644 --- a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinSerializers.kt +++ b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinSerializers.kt @@ -58,7 +58,7 @@ object ValueClassUnboxSerializer : StdSerializer(Any::class.java) { val unboxed = value::class.java.getMethod("unbox-impl").invoke(value) if (unboxed == null) { - provider.findNullValueSerializer(null).serialize(null, gen, provider) + provider.defaultSerializeNull(gen) return } @@ -77,8 +77,8 @@ internal sealed class ValueClassSerializer(t: Class) : StdSerializer // As shown in the processing of the factory function, jsonValueGetter is always a static method. val jsonValue: Any? = staticJsonValueGetter.invoke(null, unboxed) jsonValue - ?.let { provider.findValueSerializer(it::class.java).serialize(it, gen, provider) } - ?: provider.findNullValueSerializer(null).serialize(null, gen, provider) + ?.let { provider.defaultSerializeValue(it, gen) } + ?: provider.defaultSerializeNull(gen) } } diff --git a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/GitHub873.kt b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/GitHub873.kt index dfe23644..c45def86 100644 --- a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/GitHub873.kt +++ b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/github/GitHub873.kt @@ -1,11 +1,22 @@ package com.fasterxml.jackson.module.kotlin.test.github +import com.fasterxml.jackson.annotation.JsonValue import com.fasterxml.jackson.module.kotlin.defaultMapper import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.fasterxml.jackson.module.kotlin.readValue import kotlin.test.Test class GitHub873 { + @JvmInline + value class Person( + val properties: Map, + ) + + data class TimestampedPerson( + val timestamp: Long, + val person: Person, + ) + @Test fun `should serialize value class`() { @@ -35,12 +46,18 @@ class GitHub873 { } @JvmInline - value class Person( - val properties: Map, - ) + value class MapAsJsonValue(val value: String) { + @get:JsonValue + val jsonValue get() = mapOf("key" to value) + } - data class TimestampedPerson( - val timestamp: Long, - val person: Person, - ) + data class JsonValueWrapper(val value: MapAsJsonValue) + + @Test + fun `JsonValue is serialized in the same way`() { + val data = JsonValueWrapper(MapAsJsonValue("value")) + val json = defaultMapper.writeValueAsString(data) + + assert("""{"value":{"key":"value"}}""" == json) + } } From f391a8339b56c0388bf7afe35f9bec178165089d Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sun, 2 Feb 2025 14:02:56 +0900 Subject: [PATCH 2/3] Simplify defaultSerializeValue has null value consideration. https://github.com/FasterXML/jackson-databind/blob/a204131005008e42d953a929499089f7f5221218/src/main/java/com/fasterxml/jackson/databind/SerializerProvider.java#L1177-L1182 --- .../jackson/module/kotlin/KotlinSerializers.kt | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinSerializers.kt b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinSerializers.kt index 32d90c62..82bcb164 100644 --- a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinSerializers.kt +++ b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinSerializers.kt @@ -56,12 +56,6 @@ object ValueClassUnboxSerializer : StdSerializer(Any::class.java) { override fun serialize(value: Any, gen: JsonGenerator, provider: SerializerProvider) { val unboxed = value::class.java.getMethod("unbox-impl").invoke(value) - - if (unboxed == null) { - provider.defaultSerializeNull(gen) - return - } - provider.defaultSerializeValue(unboxed, gen) } } @@ -76,9 +70,7 @@ internal sealed class ValueClassSerializer(t: Class) : StdSerializer val unboxed = unboxMethod.invoke(value) // As shown in the processing of the factory function, jsonValueGetter is always a static method. val jsonValue: Any? = staticJsonValueGetter.invoke(null, unboxed) - jsonValue - ?.let { provider.defaultSerializeValue(it, gen) } - ?: provider.defaultSerializeNull(gen) + provider.defaultSerializeValue(jsonValue, gen) } } From 6027563b60a782eceb23f9c7bd61002b642c80ec Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sun, 2 Feb 2025 14:20:08 +0900 Subject: [PATCH 3/3] Update release notes wrt #908 --- release-notes/CREDITS-2.x | 1 + release-notes/VERSION-2.x | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/release-notes/CREDITS-2.x b/release-notes/CREDITS-2.x index 2da904ac..caccf7e0 100644 --- a/release-notes/CREDITS-2.x +++ b/release-notes/CREDITS-2.x @@ -18,6 +18,7 @@ Contributors: # 2.18.3 (not yet released) WrongWrong (@k163377) +* #908: Additional fixes related to #904. * #904: Fixed an error when serializing a `value class` that wraps a `Map` * #900: Fixed an issue where some tests were not running diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x index 4f3a68d9..28325127 100644 --- a/release-notes/VERSION-2.x +++ b/release-notes/VERSION-2.x @@ -18,7 +18,9 @@ Co-maintainers: 2.18.3 (not yet released) -#904: An error that occurred when serializing a `value class` that wraps a `Map`(#873) has been fixed. +#904: Fixed a problem where context was not being propagated properly when serializing an unboxed value of `value class` + or a value retrieved with `JsonValue`. + This fixes a problem where an error would occur when serializing a `value class` that wraps a `Map`(#873). 2.18.2 (27-Nov-2024) 2.18.1 (28-Oct-2024)