This module uses Kotlin extension functions, they are all defined in an Extensions.kt file and as such are accessible by importing the ExtensionsKt class. For example :

import com.fasterxml.jackson.module.kotlin.ExtensionsKt;
import com.fasterxml.jackson.databind.ObjectMapper;

ObjectMapper mapper = ExtensionsKt.jacksonObjectMapper();

If the method extends a type, for example in Kotlin :

val mapper = ObjectMapper().registerKotlinModule()

The method is defined in kotlin as :

fun ObjectMapper.registerKotlinModule(): ObjectMapper

It will be converted in java to :

public static final ObjectMapper registerKotlinModule(@NotNull ObjectMapper $this$registerKotlinModule)

So to use it, you need to pass the extended type :

ObjectMapper mapper = ExtensionsKt.registerKotlinModule(new ObjectMapper());
Answer from bcordier on Stack Overflow
🌐
GitHub
github.com › FasterXML › jackson-module-kotlin › issues › 606
ObjectMapper.registerKotlinModule does not works · Issue #606 · FasterXML/jackson-module-kotlin
November 18, 2022 - // This is a same code as above class SerializerTestcase { @Test fun testcase2() { // Initialize serializer val serializer = Jackson2JsonRedisSerializer(Any::class.java) val objectMapper = ObjectMapper().registerKotlinModule() objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY) objectMapper.activateDefaultTyping(objectMapper.polymorphicTypeValidator, ObjectMapper.DefaultTyping.NON_FINAL) serializer.setObjectMapper(objectMapper) val input = Bar(0) val bytes = serializer.serialize(input) println(bytes.toString(StandardCharsets.UTF_8)) // It prints: ["org.example.Bar",{"foo":0}] val output = serializer.deserialize(bytes) println(output) } }
Author: FasterXML
🌐
JitPack
jitpack.io › p › DanielThomas › jackson-module-kotlin
DanielThomas / jackson-module-kotlin Download
val mapper = ObjectMapper().registerKotlinModule() A simple data class example: import com.fasterxml.jackson.module.kotlin.* data class MyStateObject(val name: String, val age: Int) ...
🌐
Medium
medium.com › @bartlomiej.bobak › deserializing-a-kotlin-object-using-jackson-may-not-work-as-you-expect-1e01003cc0f0
Deserializing a Kotlin object using Jackson may not work as you expect | by Bartłomiej Bobak | Medium
February 12, 2023 - @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, property = "type" ) sealed class Scope { object All : Scope() data class Specific(val value: String): Scope() } fun main() { val objectMapper = ObjectMapper().registerKotlinModule() val json = objectMapper.writeValueAsString(Scope.All) val scope = objectMapper.readValue<Scope>(json) when (scope) { Scope.All -> println("All") is Scope.Specific -> println(scope.value) } }
🌐
Kotlinlang
slack-chats.kotlinlang.org › t › 482354 › i-want-to-use-kotlin-data-class-in-java-with-jackson-seriali
I want to use Kotlin data class in java with jackson seriali kotlinlang #jackson-kotlin
.registerKotlinModule() on the ObjectMapper · m · Maksim Vlasov06/05/2019, 10:05 AM · @Evan R. thank you! 👍 1 · 350 Views · Open in Slack · PreviousNext ·
🌐
Medium
medium.com › @js_9757 › polymorphic-json-parsing-with-kotlin-and-jackson-b7a8549fef9c
Polymorphic JSON Parsing with Kotlin and Jackson | by Jens@Fivesec | Medium
August 27, 2024 - import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.module.kotlin.registerKotlinModule import org.example.Car import org.example.Plain import org.example.Vehicles import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import kotlin.test.assertTrue class VehicleServiceTest { private lateinit var objectMapper: ObjectMapper val testPayloadPlain = """ { "type": "plain", "uuid": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "engines": 4, "spread": 2.5 } """.trimIndent() val testPayloadCar = """ { "type": "car", "uuid": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
🌐
Continuous Growth
kapentaz.github.io › home › kotlin › json
Kotlin and Jackson (ObjectMapper) - Continuous Growth
March 14, 2020 - val mapper1 = ObjectMapper().registerModule(KotlinModule()) val mapper2 = jacksonObjectMapper() val mapper3 = ObjectMapper().registerKotlinModule()
Top answer
1 of 9
102

@JsonProperty annotations in your code are all put on private fields within your data class and by default Jackson doesn't scan private fields for annotations. You have to instruct it to do otherwise by putting @JsonAutoDetect annotation:

@JsonAutoDetect(fieldVisibility = Visibility.ANY)
data class CurrencyInfo(
    @JsonProperty("currency_info") var currencyInfo: CurrencyInfoItem?
)

or alternatively you can move your annotations on accessor methods:

data class CurrencyInfo(
    @get:JsonProperty("currency_info") var currencyInfo: CurrencyInfoItem?
)
2 of 9
22

You can do something like this:

data class CurrencyInfo @JsonCreator constructor (
        @param:JsonProperty("currency_info") 
        @get:JsonProperty("currency_info")
        val currencyInfo: CurrencyInfoItem?
)

code above translates to java as:

public final class CurrencyInfo {
   @Nullable
   private final String currencyInfo;

   @JsonProperty("currency_info")
   @Nullable
   public final String getCurrencyInfo() {
      return this.currencyInfo;
   }

   @JsonCreator
   public CurrencyInfo(@JsonProperty("currency_info") @Nullable String currencyInfo) {
      this.currencyInfo = currencyInfo;
   }
}

code from accepted answer translates to java as following:

First (is not pure immutable):

@JsonAutoDetect(
   fieldVisibility = Visibility.ANY
)
public final class CurrencyInfo {
   @Nullable
   private String currencyInfo;

   @Nullable
   public final String getCurrencyInfo() {
      return this.currencyInfo;
   }

   public final void setCurrencyInfo(@Nullable String var1) {
      this.currencyInfo = var1;
   }

   public CurrencyInfo(@JsonProperty("currency_info") @Nullable String currencyInfo) {
      this.currencyInfo = currencyInfo;
   }
}

Second (probably has problems with deserialization):

public final class CurrencyInfo {
   @Nullable
   private final String currencyInfo;

   @JsonProperty("currency_info")
   @Nullable
   public final String getCurrencyInfo() {
      return this.currencyInfo;
   }

   public CurrencyInfo(@Nullable String currencyInfo) {
      this.currencyInfo = currencyInfo;
   }
}
Find elsewhere
Top answer
1 of 2
6

If you haven't gotten it to work with KotlinModule, since the problem you're having is that Jackson requires a default empty constructor and you currently don't have one. You could just change your MessageObject as follows and it should work:

  data class MessageObject(
  var id: String = "",
  var name: String = "",
  var otherId: String = ""
)

I created this repo with a fully functional kotlin lambda template using the Serverless Framework. Have a look for some other tidbits you might need: https://github.com/crafton/sls-aws-lambda-kotlin-gradlekt

2 of 2
4

You cannot use data class with provided RequestHandler<I, O> unfortunately, because you need register the kotlin module for your jackson mapper in order to work with data classes. But you can write you own RequestHandler, which will like this one.

Here's the code:

interface MyRequestStreamHandler<I : Any, O : Any?> : RequestStreamHandler {
    val inputType: Class<I>

    fun handleRequest(input: I, context: Context): O?

    override fun handleRequest(inputStream: InputStream, outputStream: OutputStream, context: Context) {
        handleRequest(inputStream.readJson(inputType), context).writeJsonNullable(outputStream)
    }

    interface MessageObjectRequestHandler : MyRequestStreamHandler< MessageObject, Output> {
        override val inputType: Class<MessageObject >
            get() = MessageObject::class.java
    }
}

And jackson util:

private val objectMapper = jacksonObjectMapper()
        .configure(JsonParser.Feature.ALLOW_COMMENTS, true)
        .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
        .registerKotlinModule()

private val writer: ObjectWriter = objectMapper.writer()

fun <T : Any> readJson(clazz: Class<T>, stream: InputStream): T =
        objectMapper.readValue(stream, clazz)

fun <T : Any> InputStream.readJson(clazz: Class<T>): T =
        readJson(clazz, this)

fun Any?.writeJsonNullable(outputStream: OutputStream) {
    if (this != null)  writer.writeValue(outputStream, this)
}

Now, you can keep your MessageObject class to be data class, and your handler will look something like:

class LambdaMain : MessageObjectRequestHandler {
    override fun handleRequest(input: MessageObject, context: Context): Output { 
        //...
    }
}
🌐
Kotlinlang
slack-chats.kotlinlang.org › t › 474221 › i-know-it-s-more-a-jackson-than-a-kotlin-question-but-i-hope
I know it s more a Jackson than a Kotlin question but I hop kotlinlang #getting-started
ObjectMapper(YAMLFactory()).registerKotlinModule() and · YAMLMapper.builder().addModule(kotlinModule()).build(). Thanks for your help! 1215 Views · Open in Slack · PreviousNext ·
🌐
JitPack
jitpack.io › p › komakai › jackson-module-kotlin
komakai / jackson-module-kotlin Download
val mapper = ObjectMapper().registerKotlinModule() A simple data class example: import com.fasterxml.jackson.module.kotlin.* data class MyStateObject(val name: String, val age: Int) ...
🌐
Medium
medium.com › @bapness › modernizing-website-updates-with-kotlin-script-and-github-1e262c70dd5b
Modernizing website updates with Kotlin Script and GitHub | by Baptiste Carlier | Medium
December 31, 2024 - /** * JACKSON */ @file:DependsOn("com.fasterxml.jackson.module:jackson-module-kotlin:2.15.2") import com.fasterxml.jackson.databind.DeserializationFeature import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.module.kotlin.readValue import com.fasterxml.jackson.module.kotlin.registerKotlinModule
🌐
Scaladex
index-dev.scala-lang.org › fasterxml › jackson-module-kotlin
Scaladex - fasterxml / jackson-module-kotlin
In 2.17 and later, the jacksonObjectMapper {} and registerKotlinModule {} lambdas allow configuration for KotlinModule.
🌐
Medium
medium.com › codex › how-to-deal-with-empty-lists-that-defaults-to-null-in-jackson-and-kotlin-ef865da0080f
How to deal with empty lists that defaults to null in Jackson and Kotlin | by Isaias Velasquez | CodeX | Medium
April 25, 2024 - The simplest to this, using Jackson 2.17 (most recent version to the date this article was written) was to declare the Jackson Kotlin Module manually, and instead of using ObjectMapper.registerKotlinModule(), use this:
🌐
Maven Repository
mvnrepository.com › artifact › com.fasterxml.jackson.module › jackson-module-kotlin
Maven Repository: com.fasterxml.jackson.module » jackson-module-kotlin
1 month ago - Add-on module for Jackson (https://github.com/FasterXML/jackson/) to support Kotlin language, specifically introspection of method/constructor parameter names, without having to add explicit property name annotation · Web site developed by @frodriguez Powered by: Scala, Play, Spark, Pekko ...