Parsing with Jackson and Kotlin
An introduction to Jackson Kotlin module and Kotlin nullable type for missing values in data

Jackson is one of the famous library to parse XML or JSON data though with Kotlin, some key factors are required to avoid unexpected issues.
Need of Default Constructor
By default, Java provides a default constructor(if there’s no parameterized constructor) which is used by Jackson
to parse the response into POJO or bean classes.
Kotlin provides a feature of data
classes which do not provide a default constructor(instead, it uses a parameterise constructor) so parsing a response in Kotlin will result in InvalidDefinitionException
exception as:
where the Person
class is a simple data
class with two properties
data class Person(var name: String, var occupation: String)
and the exception log.
Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `Person` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: (String)"{
"name": "Pavneet",
"occupation": "Software Engineer"
}"
Data classes has a restriction to have at-least one primary constructor parameter so no default/no-args constructor is available by default in data classes.
Jackson is unable to find the default constructor so it’s unable to create an object of Person
class and throwing the InvalidDefinitionException
exception.
This issue can be fixed by using @JsonProperty
annotation which will instruct Jackson
to use setters and getter for parsing as:
The exception can also be fixed by creating a normal class instead of data
class as:
Internally, compiler will generate public
setters/getter to access the properties of class
and will have a provision of default constructor.
Jackson Kotlin Module
Adding JsonProperty
is convenient when the property names are different than the response (which is not our use case). Alternately, Jackson
provides a separate module jackson-module-kotlin which has KotlinModule
class to fix this issue as:
The KotlinModule
can be registered at runtime with mapper object as :
val mapper = ObjectMapper().registerModule(KotlinModule())
Now there is no need to add @JsonProperty
to data/model classes.
KotlinModule
internally uses Kotlin specific reflection APIs which handles the mapping of KClass
, KFunction
to java classes with the help of kotlin.jvm and kotlin.reflect.jvm
packages.
Handling Missing Values
By default, Jackson use null
for missing values but you may have guessed, Kotlin does not allow null
as a value so if a value is missing like occupation
{
"name": "Pavneet",
}
then occupation
property needs to be marked as nullable in Kotlin by using ?
to avoid exceptions as: