Sergey Akhapkin
09/17/2021, 1:33 PM@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
sealed class A {
@JsonTypeName("B")
object B: A()
@JsonTypeName("C")
object C: A()
@JsonTypeName("D")
data class D(val i: Int): A()
}
class JsonTest {
private val objectMapper = jacksonObjectMapper().apply(configureObjectMapper)
private fun <T> parse(str: String, clazz: Class<T>): T = objectMapper.readValue(str, clazz)
private fun <T> stringify(value: T): String = objectMapper.writeValueAsString(value)
@Test
fun testPatternMatching() {
val x1 = A.B
val x2 = parse(stringify(x1), A::class.java)
val x3 = A.C
listOf(x1,x2,x3).forEach {
when(it) {
A.B -> println("b ${it as Any}")
A.C -> println("c ${it as Any}")
is A.D -> println("d ${it as Any}")
else -> println("? ${it as Any}")
}
}
assertEquals(A.B, x1)
assertEquals(A.B, x2) // <--- failed assertion in 1.4.30
assertEquals(x1, x2)
}
}
In 1.3.50 projects, it prints:
b com.example.A$B@184a254d
b com.example.A$B@184a254d
c com.example.A$C@41443428
In 1.4.30 (and 1.5.x) projects, it prints:
b com.example.A$B@12a1cc8d
? com.example.A$B@7b2edf94
c com.example.A$C@73baae4e
and test fails with
expected:<com.example.A$B@12a1cc8d> but was:<com.example.A$B@7b2edf94>
As I can see - after serialization/deserialation I got 2nd A.B object (nonsense for a singleton). This code can be fixed by writting 'is A.B', in that case both instances (x1 and x2) will be matched.
But who knows what is going on here and why it changed since 1.4.x ?Emil Kantis
09/17/2021, 1:50 PMkotlinx.serialization
Sergey Akhapkin
09/17/2021, 1:55 PMEmil Kantis
09/17/2021, 1:58 PMEmil Kantis
09/17/2021, 1:59 PMSergey Akhapkin
09/17/2021, 2:09 PMjackson_version=2.10.2
In 1.4.x project:
jackson_version=2.12.1
Sergey Akhapkin
09/17/2021, 2:10 PMEmil Kantis
09/17/2021, 2:11 PMSergey Akhapkin
09/17/2021, 2:15 PMEmil Kantis
09/17/2021, 2:19 PMEmil Kantis
09/17/2021, 2:19 PMSergey Akhapkin
09/17/2021, 2:40 PMSergey Akhapkin
09/17/2021, 2:56 PMephemient
09/17/2021, 4:32 PMSergey Akhapkin
09/17/2021, 7:39 PMfun jacksonObjectMapper(): ObjectMapper = jsonMapper { addModule(kotlinModule()) }
but it leads to using wrong (default setting) for kotlin singletons.
Correct usage will be:
KotlinModule(singletonSupport = SingletonSupport.CANONICALIZE)
Sergey Akhapkin
09/17/2021, 7:44 PM