Note: Failed to Read Get Kotlin Metadata for
Overview
Module that adds support for serialization/deserialization of Kotlin classes and data classes. Previously a default constructor must accept existed on the Kotlin object for Jackson to deserialize into the object. With this module, single constructor classes can be used automatically, and those with secondary constructors or static factories are also supported.
Status
Releases crave that yous accept included Kotlin stdlib and reflect libraries already.
Gradle:
implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.13.+"
Maven:
<dependency> <groupId>com.fasterxml.jackson.module</groupId> <artifactId>jackson-module-kotlin</artifactId> <version>2.13.0</version> </dependency>
Usage
For any Kotlin class or data class constructor, the JSON property names will be inferred from the parameters using Kotlin runtime type information.
To apply, just register the Kotlin module with your ObjectMapper example:
// With Jackson ii.12 and later import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper ... val mapper = jacksonObjectMapper() // or import com.fasterxml.jackson.module.kotlin.registerKotlinModule ... val mapper = ObjectMapper().registerKotlinModule() // or import com.fasterxml.jackson.module.kotlin.jsonMapper import com.fasterxml.jackson.module.kotlin.kotlinModule ... val mapper = jsonMapper { addModule(kotlinModule()) }
Jackson versions prior to 2.ten–2.11
import com.fasterxml.jackson.databind.json.JsonMapper import com.fasterxml.jackson.module.kotlin.KotlinModule ... val mapper = JsonMapper.builder().addModule(KotlinModule()).build()
Jackson versions prior to 2.x
import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.module.kotlin.KotlinModule ... val mapper = ObjectMapper().registerModule(KotlinModule())
A simple data form example:
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.fasterxml.jackson.module.kotlin.readValue information class MyStateObject(val name : Cord, val age : Int) ... val mapper = jacksonObjectMapper() val state = mapper.readValue<MyStateObject>(json) // or val country: MyStateObject = mapper.readValue(json) // or myMemberWithType = mapper.readValue(json)
All inferred types for the extension functions carry in full generic information (reified generics). Therefore, using readValue()
extension without the Class
parameter will reify the type and automatically create a TypeReference
for Jackson.
Also, in that location are some convenient operator overloading extension functions for JsonNode inheritors.
import com.fasterxml.jackson.databind.node.ArrayNode import com.fasterxml.jackson.databind.node.ObjectNode import com.fasterxml.jackson.databind.node.JsonNodeFactory import com.fasterxml.jackson.module.kotlin.* // ... val objectNode: ObjectNode = JsonNodeFactory.example.objectNode() objectNode.put( "foo1" , "bar" ).put( "foo2" , "baz" ).put( "foo3" , "bax" ) objectNode - = "foo1" objectNode - = listOf( "foo2" ) println(objectNode.toString()) // {"foo3":"bax"} // ... val arrayNode: ArrayNode = JsonNodeFactory.instance.arrayNode() arrayNode + = "foo" arrayNode + = truthful arrayNode + = 1 arrayNode + = 1.0 arrayNode + = "bar" .toByteArray() println(arrayNode.toString()) // ["foo",truthful,1,1.0,"YmFy"]
Annotations
You lot tin intermix non-field values in the constructor and JsonProperty
note in the constructor. Whatsoever fields not nowadays in the constructor volition be fix later on the constructor call. An case of these concepts:
@JsonInclude(JsonInclude.Include.NON_EMPTY) class StateObjectWithPartialFieldsInConstructor(val proper noun : String, @JsonProperty( "historic period" ) val years : Int) { @JsonProperty( "address" ) lateinit var primaryAddress: String // set after structure var createdDt: DateTime past Delegates.notNull() // set afterwards structure var neverSetProperty: String? = null // non in JSON so must be nullable with default }
Notation that using lateinit
or Delegates.notNull()
will ensure that the value is never null
when read, while letting it exist instantiated after the construction of the class.
Caveats
- The
@JsonCreator
note is optional unless you have more than than one constructor that is valid, or you want to use a static manufacturing plant method (which too must takeplatformStatic
notation, e.g.@JvmStatic
). In these cases, comment only one method asJsonCreator
. - Serializing a fellow member or top-level Kotlin class that implements Iterator requires a workaround, come across Issue #4 for easy workarounds.
- If using proguard:
-
kotlin.Metadata
annotations may exist stripped, preventing deserialization. Add a proguard rule to keep thekotlin.Metadata
class:-keep class kotlin.Metadata { *; }
- If yous're getting
java.lang.ExceptionInInitializerError
, y'all may also need:-proceed class kotlin.reflect.** { *; }
- If you're still running into problems, you lot might also demand to add a proguard keep rule for the specific classes you desire to (de-)serialize. For case, if all your models are inside the packet
com.example.models
, yous could add together the rule-keep class com.example.models.** { *; }
-
Support for Kotlin Built-in classes
These Kotlin classes are supported with the following fields for serialization/deserialization (and other fields are hidden that are non relevant):
- Pair (first, 2nd)
- Triple (commencement, second, third)
- IntRange (starting time, end)
- CharRange (showtime, stop)
- LongRange (start, terminate)
(others are likely to work, but may not be tuned for Jackson)
Sealed classes without @JsonSubTypes
Subclasses can be detected automatically for sealed classes, since all possible subclasses are known at compile-time to Kotlin. This makes com.fasterxml.jackson.annotation.JsonSubTypes
redundant. A com.fasterxml.jackson.annotation.@JsonTypeInfo
notation at the base of operations-course is still necessary.
@JsonTypeInfo(use = JsonTypeInfo.Id.Name) sealed class SuperClass{ form A: SuperClass() grade B: SuperClass() } ... val mapper = jacksonObjectMapper() val root: SuperClass = mapper.readValue(json) when(root){ is A -> "It'due south A" is B -> "It's B" }
Configuration
The Kotlin module may be given a few configuration parameters at construction time; see the inline documentation for details on what options are available and what they do.
val mapper = JsonMapper.builder() .addModule(KotlinModule(strictNullChecks = truthful)) .build()
If your ObjectMapper
is constructed in Java, there is a architect method provided for configuring these options:
KotlinModule kotlinModule = new KotlinModule.Builder() .strictNullChecks(truthful) .build(); ObjectMapper objectMapper = JsonMapper .builder() .addModule(kotlinModule) .build();
Evolution
Maintainers
Post-obit developers have committer access to this project.
- Writer: Jayson Minard (@apatrida) wrote this module; even so helps issues from time to time
- Active Maintainers:
- Drew Stephens (@dinomite)
- Vyacheslav Artemyev (@viartemev)
- Co-maintainers:
- Tatu Saloranta (@cowtowncoder)
You may at-reference them equally necessary simply please keep in mind that all maintenance piece of work is strictly voluntary (no one gets paid to piece of work on this or any other Jackson components) so there is no guarantee for timeliness of responses.
All Pull Requests should be reviewed past at to the lowest degree 1 of active maintainers; bigger architectural/design questions should exist agreed upon past majority of agile maintainers (at this point meaning both Drew and Vyacheslav :) ).
Releases & Branches
This module follows the release schedule of the rest of Jackson—the current version is consistent across all Jackson components & modules. See the jackson-databind README for details.
Contributing
We welcome whatever contributions—reports of issues, ideas for enhancements, and pull requests related to either of those.
Come across the main Jackson contribution guidlines for more details.
Branches
If you are going to write code, choose the appropriate base branch:
-
2.12
for bugfixes confronting the current stable version -
2.13
for additive functionality & features or small-scale, backwards compatible changes to existing behavior to exist included in the side by side minor version release -
principal
for significant changes to existing behavior, which will be part of Jackson 3.0
Declining tests
In that location are a number of tests for functionality that is broken, more often than not in the failing package but a few as part of other test suites. Instead of ignoring these tests (with JUnit's @Ignore
annotation) or excluding them from being run every bit part of automated testing, the tests are written to demonstrate the failure (either making a call that throws an exception or with an assertion that fails) simply not fail the build, except if the underlying outcome is fixed. This allows us to know when the tested functionality has been incidentally fixed by unrelated code changes.
See the tests readme for more information.
Source: https://github.com/FasterXML/jackson-module-kotlin
0 Response to "Note: Failed to Read Get Kotlin Metadata for"
Post a Comment