diff --git a/release-notes/CREDITS-2.x b/release-notes/CREDITS-2.x index 6fe440f2..309b593f 100644 --- a/release-notes/CREDITS-2.x +++ b/release-notes/CREDITS-2.x @@ -21,6 +21,7 @@ Stefan Schmid (schmist@github) wrongwrong (k163377@github) * #456: Refactor KNAI.findImplicitPropertyName() * #449: Refactor AnnotatedMethod.hasRequiredMarker() +* #521: Fixed lookup of instantiators Dmitri Domanine (novtor@github) * Contributed fix for #490: Missing value of type JsonNode? is deserialized as NullNode instead of null diff --git a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinValueInstantiator.kt b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinValueInstantiator.kt index 2196d968..519b31ab 100644 --- a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinValueInstantiator.kt +++ b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinValueInstantiator.kt @@ -201,8 +201,15 @@ internal class KotlinInstantiators( defaultInstantiator: ValueInstantiator ): ValueInstantiator { return if (beanDescriptor.beanClass.isKotlinClass()) { - if (defaultInstantiator is StdValueInstantiator) { - KotlinValueInstantiator(defaultInstantiator, cache, nullToEmptyCollection, nullToEmptyMap, nullIsSameAsDefault, strictNullChecks) + if (defaultInstantiator::class == StdValueInstantiator::class) { + KotlinValueInstantiator( + defaultInstantiator as StdValueInstantiator, + cache, + nullToEmptyCollection, + nullToEmptyMap, + nullIsSameAsDefault, + strictNullChecks + ) } else { // TODO: return defaultInstantiator and let default method parameters and nullability go unused? or die with exception: throw IllegalStateException("KotlinValueInstantiator requires that the default ValueInstantiator is StdValueInstantiator") diff --git a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/KotlinInstantiatorsTest.kt b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/KotlinInstantiatorsTest.kt new file mode 100644 index 00000000..dad0fc60 --- /dev/null +++ b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/KotlinInstantiatorsTest.kt @@ -0,0 +1,65 @@ +package com.fasterxml.jackson.module.kotlin + +import com.fasterxml.jackson.databind.deser.std.StdValueInstantiator +import org.junit.Assert.* +import org.junit.Test + +class KotlinInstantiatorsTest { + private val mapper = jacksonObjectMapper() + private val deserConfig = mapper.deserializationConfig + + private val kotlinInstantiators = KotlinInstantiators( + ReflectionCache(10), + nullToEmptyCollection = false, + nullToEmptyMap = false, + nullIsSameAsDefault = false, + strictNullChecks = false + ) + + @Test + fun `Provides default instantiator for Java class`() { + val javaType = mapper.constructType(String::class.java) + val defaultInstantiator = StdValueInstantiator(deserConfig, javaType) + val instantiator = kotlinInstantiators.findValueInstantiator( + deserConfig, + deserConfig.introspect(javaType), + defaultInstantiator + ) + + assertEquals(defaultInstantiator, instantiator) + } + + @Test + fun `Provides KotlinValueInstantiator for Kotlin class`() { + class TestClass + + val javaType = mapper.constructType(TestClass::class.java) + val instantiator = kotlinInstantiators.findValueInstantiator( + deserConfig, + deserConfig.introspect(javaType), + StdValueInstantiator(deserConfig, javaType) + ) + + assertTrue(instantiator is StdValueInstantiator) + assertTrue(instantiator::class == KotlinValueInstantiator::class) + } + + @Test + fun `Throws for Kotlin class when default instantiator isn't StdValueInstantiator`() { + class TestClass + class DefaultClass + + val subClassInstantiator = object : StdValueInstantiator( + deserConfig, + mapper.constructType(DefaultClass::class.java) + ) {} + + assertThrows(IllegalStateException::class.java) { + kotlinInstantiators.findValueInstantiator( + deserConfig, + deserConfig.introspect(mapper.constructType(TestClass::class.java)), + subClassInstantiator + ) + } + } +} \ No newline at end of file