Skip to content

Commit 1bc121d

Browse files
authored
Merge pull request #521 from k163377/fix-findValueInstantiator
Fixed an issue that could cause unexpected behavior when an instance that inherits from `StdValueInstantiator` is passed to `defaultInstantiator`.
2 parents 0de1216 + 7b59597 commit 1bc121d

File tree

3 files changed

+75
-2
lines changed

3 files changed

+75
-2
lines changed

release-notes/CREDITS-2.x

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Stefan Schmid (schmist@github)
2121
wrongwrong (k163377@github)
2222
* #456: Refactor KNAI.findImplicitPropertyName()
2323
* #449: Refactor AnnotatedMethod.hasRequiredMarker()
24+
* #521: Fixed lookup of instantiators
2425

2526
Dmitri Domanine (novtor@github)
2627
* Contributed fix for #490: Missing value of type JsonNode? is deserialized as NullNode instead of null

src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinValueInstantiator.kt

+9-2
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,15 @@ internal class KotlinInstantiators(
201201
defaultInstantiator: ValueInstantiator
202202
): ValueInstantiator {
203203
return if (beanDescriptor.beanClass.isKotlinClass()) {
204-
if (defaultInstantiator is StdValueInstantiator) {
205-
KotlinValueInstantiator(defaultInstantiator, cache, nullToEmptyCollection, nullToEmptyMap, nullIsSameAsDefault, strictNullChecks)
204+
if (defaultInstantiator::class == StdValueInstantiator::class) {
205+
KotlinValueInstantiator(
206+
defaultInstantiator as StdValueInstantiator,
207+
cache,
208+
nullToEmptyCollection,
209+
nullToEmptyMap,
210+
nullIsSameAsDefault,
211+
strictNullChecks
212+
)
206213
} else {
207214
// TODO: return defaultInstantiator and let default method parameters and nullability go unused? or die with exception:
208215
throw IllegalStateException("KotlinValueInstantiator requires that the default ValueInstantiator is StdValueInstantiator")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package com.fasterxml.jackson.module.kotlin
2+
3+
import com.fasterxml.jackson.databind.deser.std.StdValueInstantiator
4+
import org.junit.Assert.*
5+
import org.junit.Test
6+
7+
class KotlinInstantiatorsTest {
8+
private val mapper = jacksonObjectMapper()
9+
private val deserConfig = mapper.deserializationConfig
10+
11+
private val kotlinInstantiators = KotlinInstantiators(
12+
ReflectionCache(10),
13+
nullToEmptyCollection = false,
14+
nullToEmptyMap = false,
15+
nullIsSameAsDefault = false,
16+
strictNullChecks = false
17+
)
18+
19+
@Test
20+
fun `Provides default instantiator for Java class`() {
21+
val javaType = mapper.constructType(String::class.java)
22+
val defaultInstantiator = StdValueInstantiator(deserConfig, javaType)
23+
val instantiator = kotlinInstantiators.findValueInstantiator(
24+
deserConfig,
25+
deserConfig.introspect(javaType),
26+
defaultInstantiator
27+
)
28+
29+
assertEquals(defaultInstantiator, instantiator)
30+
}
31+
32+
@Test
33+
fun `Provides KotlinValueInstantiator for Kotlin class`() {
34+
class TestClass
35+
36+
val javaType = mapper.constructType(TestClass::class.java)
37+
val instantiator = kotlinInstantiators.findValueInstantiator(
38+
deserConfig,
39+
deserConfig.introspect(javaType),
40+
StdValueInstantiator(deserConfig, javaType)
41+
)
42+
43+
assertTrue(instantiator is StdValueInstantiator)
44+
assertTrue(instantiator::class == KotlinValueInstantiator::class)
45+
}
46+
47+
@Test
48+
fun `Throws for Kotlin class when default instantiator isn't StdValueInstantiator`() {
49+
class TestClass
50+
class DefaultClass
51+
52+
val subClassInstantiator = object : StdValueInstantiator(
53+
deserConfig,
54+
mapper.constructType(DefaultClass::class.java)
55+
) {}
56+
57+
assertThrows(IllegalStateException::class.java) {
58+
kotlinInstantiators.findValueInstantiator(
59+
deserConfig,
60+
deserConfig.introspect(mapper.constructType(TestClass::class.java)),
61+
subClassInstantiator
62+
)
63+
}
64+
}
65+
}

0 commit comments

Comments
 (0)