jackson-module-kotlin icon indicating copy to clipboard operation
jackson-module-kotlin copied to clipboard

Using default parameters does not work if they are not serializable even if not used by Jackson

Open alturkovic opened this issue 1 year ago • 0 comments

Search before asking

  • [X] I searched in the issues and found nothing similar.
  • [X] I searched in the issues of databind and other modules used and found nothing similar.
  • [X] I have confirmed that the problem only occurs when using Kotlin.

Describe the bug

When using a default parameter that is not serializable, such as a Random, the deserialization fails. In my example, the exception is:

Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `kotlin.random.Random` (no Creators, like default constructor, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
 at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 2]
	at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
	at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1887)
	at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:414)
	at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1375)
	at com.fasterxml.jackson.databind.deser.AbstractDeserializer.deserialize(AbstractDeserializer.java:274)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1486)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:348)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:185)
	at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:342)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4905)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3848)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3831)
	at app.interceptor.core.filter.TestingKt.main(testing.kt:19)
	at app.interceptor.core.filter.TestingKt.main(testing.kt)

To Reproduce

import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import kotlin.random.Random

fun main() {
    val mapper = jacksonObjectMapper()
    val component = Component()
    val json = mapper.writeValueAsString(component)
    println(json) // {} works correctly
    println(mapper.readValue<Component>(json)) // fails
}

data class Component(
    private val random: Random = Random
)

Expected behavior

I would expect this example to work since the value has a declared default value.

Versions

Kotlin: 2.0.20 Jackson-module-kotlin: 2.17.2 Jackson-databind: 2.17.2

Additional context

No response

alturkovic avatar Aug 29 '24 09:08 alturkovic