Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@
package io.temporal.common.converter

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.KotlinModule
import com.fasterxml.jackson.module.kotlin.registerKotlinModule

class KotlinObjectMapperFactory {
companion object {
@JvmStatic
fun new(): ObjectMapper {
val mapper = JacksonJsonPayloadConverter.newDefaultObjectMapper()

// use deprecated constructor instead of builder to maintain compatibility with old jackson versions
@Suppress("deprecation")
val km = KotlinModule()
mapper.registerModule(km)
return mapper
// Let jackson-module-kotlin construct the module rather than calling a constructor here.
// `KotlinModule()` compiles to the synthetic all-defaults overload of its deprecated
// constructor, and that parameter list changed in 2.11, 2.12 and 2.16, so the call only
// linked against the versions sharing the shape we happened to build against and threw
// NoSuchMethodError on every other version. `registerKotlinModule` has kept a single
// signature since 2.9.0, which is the whole Jackson range this SDK supports.
return JacksonJsonPayloadConverter.newDefaultObjectMapper().registerKotlinModule()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package io.temporal.common.converter

import org.junit.Assert.assertEquals
import org.junit.Test

class KotlinObjectMapperFactoryTest {

data class TestPayload(val name: String, val count: Int)

/**
* A data class has no no-arg constructor, so Jackson can only deserialize it when the Kotlin
* module is registered. This also guards against [KotlinObjectMapperFactory.new] failing to link
* against the jackson-module-kotlin version present at runtime, which is not necessarily the one
* the SDK was compiled against.
*/
@Test
fun `new should return a mapper that round-trips a Kotlin data class`() {
val mapper = KotlinObjectMapperFactory.new()

val value = TestPayload("payload", 42)
val roundTripped = mapper.readValue(mapper.writeValueAsString(value), TestPayload::class.java)

assertEquals(value, roundTripped)
}
}