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

java.lang.IllegalStateException: KotlinValueInstantiator requires that the default ValueInstantiator is StdValueInstantiator

Open lukas-krecan opened this issue 2 years ago • 10 comments

Describe the bug After updating to 2.13.1 our tests started to fail with

KotlinValueInstantiator requires that the default ValueInstantiator is StdValueInstantiator
java.lang.IllegalStateException: KotlinValueInstantiator requires that the default ValueInstantiator is StdValueInstantiator
	at com.fasterxml.jackson.module.kotlin.KotlinInstantiators.findValueInstantiator(KotlinValueInstantiator.kt:215)
	at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.findValueInstantiator(BasicDeserializerFactory.java:230)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer(BeanDeserializerFactory.java:261)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:150)
	at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:415)
	at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:350)
	at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264)
	at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244)
	at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142)
	at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:642)
	at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:4805)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4675)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3629)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3612)

To Reproduce Trying to serialize Kotlin object that has Kotlin object values

Expected behavior To not fail

Versions Kotlin: Jackson-module-kotlin: 2.13.1 Jackson-databind: 2.13.1

Additional context Seems to be introduced by this commit. In our case defaultInstantiator is KotlinValueInstantiator.

lukas-krecan avatar Dec 22 '21 09:12 lukas-krecan

Most likely caused by our usage of MapperFeature.IGNORE_DUPLICATE_MODULE_REGISTRATIONS

This is how we instantiate the ObjectMapper

val objectMapper = Jackson2ObjectMapperBuilder().featuresToDisable(MapperFeature.IGNORE_DUPLICATE_MODULE_REGISTRATIONS).build<ObjectMapper>().apply {
     registerModule(KotlinModule.Builder().configure(KotlinFeature.SingletonSupport, true).build())
}

If we drop featuresToDisable(MapperFeature.IGNORE_DUPLICATE_MODULE_REGISTRATIONS) it works

lukas-krecan avatar Dec 22 '21 09:12 lukas-krecan

We have rewritten the object mapper initialization code to not register the Kotlin module twice. I am not sure if it's a bug anymore, feel free to close this if you deem fit.

lukas-krecan avatar Dec 22 '21 09:12 lukas-krecan

Huh, interesting, thanks for providing the details!

@k163377 Any ideas?

dinomite avatar Dec 22 '21 11:12 dinomite

The fact that the Kotlin Module was registered twice seems to be an unusual situation. Therefore, I think that the behavior is as intended for this situation.

However, the change may have been a bit rash, considering the compatibility when used with other modules that rewrite the defaultInstantiator. Are there any design guidelines for compatibility when multiple modules are registered? If it violates those design guidelines, I think it's better to fix it.

k163377 avatar Dec 22 '21 14:12 k163377

I don't know what the expectations are for module interactions, but @cowtowncoder might. I'd expect our (Kotlin module's) causing explosions isn't what we want—I, too, wasn't thinking in that context.

dinomite avatar Dec 23 '21 19:12 dinomite

when this scenario is possible.

val mapper = jacksonObjectMapper()

mapper.disable(IGNORE_DUPLICATE_MODULE_REGISTRATIONS)

mapper.findAndRegisterModules()   // kotlin module is register twice

debop avatar Apr 28 '22 12:04 debop

I'm experiencing the same issue,but in our case this is a flaky failure, like 1 in 10 build fails.

I guess it has to do something with parallel junit execution, but I can't find where the double registration happens.

sanyarnd avatar Sep 15 '22 19:09 sanyarnd

i have the same problem .. running my integration tests in parallel (vertx)

maybe its this call in my case DatabindCodec.mapper().registerKotlinModule()

is this expected to be thread safe?

Caused by: java.lang.IllegalStateException: KotlinValueInstantiator requires that the default ValueInstantiator is StdValueInstantiator at com.fasterxml.jackson.module.kotlin.KotlinInstantiators.findValueInstantiator(KotlinValueInstantiator.kt:174) at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.findValueInstantiator(BasicDeserializerFactory.java:230) at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer(BeanDeserializerFactory.java:261) at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:150) at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:415) at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:350) at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264) at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244) at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142) at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:642) at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:4805) at com.fasterxml.jackson.databind.ObjectMapper._readValue(ObjectMapper.java:4650) at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2831) at io.vertx.core.json.jackson.DatabindCodec.fromParser(DatabindCodec.java:126) ... 69 more

bitkid avatar Oct 05 '22 20:10 bitkid

Anyone want to do a trivial little PR to include Actual Classname of the Thing That Is Not StdValueInstantiator? That'd make it much easier to resolve whatever the root cause is (it may be in jackson-databind).

cowtowncoder avatar Oct 05 '22 22:10 cowtowncoder

i moved the call "DatabindCodec.mapper().registerKotlinModule()" to a static initialiser instead of calling it multithreaded and it seems the problem went away .. as soon as it pops up again i will post again

bitkid avatar Oct 06 '22 08:10 bitkid