Search code examples
springkotlinreferencejacksonobjectmapper

Kotlin sealed class Jackson different place in memory


Recently, I have started with Kotlin and I encountered some strange behavior while testing JSON mapping with Spring. I created something like this:

@SpringBootTest(classes = [TestApplication::class])
class JacksonIntegrationTest {

    @Autowired
    lateinit var objectMapper: ObjectMapper

    var objectMapperTest = TestObjectMapper()

    @Test
    fun `should serialize and deserialize object`() {
        //given
        val value = SealedObject

        //when
        val jsonTest = objectMapperTest.writeValueAsString(value)
        val resultTest: SealedObject = objectMapperTest.readValue(jsonTest)

        val json = objectMapper.writeValueAsString(value)
        val result: SealedObject = objectMapper.readValue(json)

        //then`
        assertThat(result).isSameAs(value)
        assertThat(resultTest).isSameAs(value) <---------- FAILED
    }
    internal sealed class Sealed
    internal object SealedObject: Sealed()
}

value = JacksonIntegrationTest$SealedObject@6727e0cd <-------------\
result (SPRING) = JacksonIntegrationTest$SealedObject@6727e0cd <----- SAME MEMORY PLACE
resultTest (OWN) = JacksonIntegrationTest$SealedObject@3c8e3f98

As you can see, spring objectmapper returned value with same reference at memory as origin value. But own created ObjectMapper returned object at different place at memory. Why?

All results should've same memory place


Solution

  • Okay, I've found a solution.

    .registerModule(
                kotlinModule(
                    initializer = {
                        configure(KotlinFeature.SingletonSupport, true)
                    },
                ),
            )