Skip to content

Commit

Permalink
Merge pull request #521 from k163377/fix-findValueInstantiator
Browse files Browse the repository at this point in the history
Fixed an issue that could cause unexpected behavior when an instance that inherits from `StdValueInstantiator` is passed to `defaultInstantiator`.
  • Loading branch information
dinomite authored Nov 26, 2021
2 parents 0de1216 + 7b59597 commit 1bc121d
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 2 deletions.
1 change: 1 addition & 0 deletions release-notes/CREDITS-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
Original file line number Diff line number Diff line change
@@ -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
)
}
}
}

0 comments on commit 1bc121d

Please sign in to comment.