Skip to content

Commit 6cfdbb7

Browse files
committed
Merge remote-tracking branch 'FasterXML/2.x' into 3.x
2 parents 900bfcb + ba0116e commit 6cfdbb7

File tree

12 files changed

+29
-273
lines changed

12 files changed

+29
-273
lines changed

release-notes/CREDITS-2.x

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ Contributors:
1818
# 2.21.0 (not yet released)
1919

2020
WrongWrong (@k163377)
21+
* #1043: Cleanup of deprecated contents
22+
* #1042: Remove old StrictNullChecks
23+
* #1041: Remove MissingKotlinParameterException
2124
* #1039: Update settings for 2.20
2225

2326
# 2.20.0 (28-Aug-2025)

release-notes/VERSION-2.x

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ Co-maintainers:
1818

1919
2.21.0 (not yet released)
2020

21+
#1043: Deprecated content has been cleaned up with the version upgrade.
22+
#1042: The old StrictNullChecks backend has been removed.
23+
This improves the throughput of deserialization slightly.
24+
#1041: The deprecated MissingKotlinParameterException has been removed.
2125
#1039: Kotlin has been upgraded to 2.1.x.
2226

2327
2.20.0 (28-Aug-2025)

src/main/kotlin/tools/jackson/module/kotlin/Exceptions.kt

Lines changed: 0 additions & 29 deletions
This file was deleted.

src/main/kotlin/tools/jackson/module/kotlin/KotlinFeature.kt

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,12 @@ enum class KotlinFeature(internal val enabledByDefault: Boolean) {
3939
*
4040
* With this disabled, the default, collections which are typed to disallow null members (e.g. `List<String>`)
4141
* may contain null values after deserialization.
42-
* Enabling it protects against this but has significant performance impact.
42+
* Enabling this will cause an [InvalidNullException] to be thrown if null is entered.
43+
*
44+
* Internally, it will be the same as if [JsonSetter] (contentNulls = FAIL) had been granted.
45+
*
46+
* Benchmarks show that it can check for illegal nulls with throughput nearly identical to the default (see [jackson-module-kotlin#719]).
4347
*/
44-
@Deprecated(
45-
level = DeprecationLevel.ERROR,
46-
message = "This option will be migrated to the new backend in 2.21.",
47-
replaceWith = ReplaceWith("NewStrictNullChecks")
48-
)
4948
StrictNullChecks(enabledByDefault = false),
5049

5150
/**
@@ -79,18 +78,18 @@ enum class KotlinFeature(internal val enabledByDefault: Boolean) {
7978
* Internally, it will be the same as if [JsonSetter] (contentNulls = FAIL) had been granted.
8079
* Benchmarks show that it can check for illegal nulls with throughput nearly identical to the default (see [jackson-module-kotlin#719]).
8180
*
82-
* Note that in the new backend, the exception thrown has changed from [MissingKotlinParameterException] to [InvalidNullException].
83-
* The message will be changed accordingly.
84-
* Since 2.19, the base class of [MissingKotlinParameterException] has also been changed to [InvalidNullException],
85-
* so be careful when catching it.
86-
*
8781
* This is a temporary option for a phased backend migration,
8882
* which will eventually be merged into [StrictNullChecks].
8983
* Also, specifying both this and [StrictNullChecks] is not permitted.
9084
*
9185
* Since 3.0, this option is enabled by default.
9286
*/
93-
NewStrictNullChecks(enabledByDefault = true);
87+
@Deprecated(
88+
level = DeprecationLevel.WARNING,
89+
message = "This option will be merged into StrictNullChecks in 2.23.",
90+
replaceWith = ReplaceWith("StrictNullChecks")
91+
)
92+
NewStrictNullChecks(enabledByDefault = false);
9493

9594
internal val bitSet: BitSet = (1 shl ordinal).toBitSet()
9695

src/main/kotlin/tools/jackson/module/kotlin/KotlinModule.kt

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,11 @@ class KotlinModule private constructor(
3434
val nullToEmptyMap: Boolean = NullToEmptyMap.enabledByDefault,
3535
val nullIsSameAsDefault: Boolean = NullIsSameAsDefault.enabledByDefault,
3636
val singletonSupport: Boolean = SingletonSupport.enabledByDefault,
37-
@Suppress("DEPRECATION_ERROR")
3837
strictNullChecks: Boolean = StrictNullChecks.enabledByDefault,
3938
val kotlinPropertyNameAsImplicitName: Boolean = KotlinPropertyNameAsImplicitName.enabledByDefault,
4039
val useJavaDurationConversion: Boolean = UseJavaDurationConversion.enabledByDefault,
41-
private val newStrictNullChecks: Boolean = NewStrictNullChecks.enabledByDefault,
40+
newStrictNullChecks: Boolean = NewStrictNullChecks.enabledByDefault,
4241
) : SimpleModule(KotlinModule::class.java.name, PackageVersion.VERSION) {
43-
44-
private val oldStrictNullChecks: Boolean = strictNullChecks
45-
4642
// To reduce the amount of destructive changes, no properties will be added to the public.
4743
val strictNullChecks: Boolean = if (strictNullChecks) {
4844
if (newStrictNullChecks) {
@@ -87,7 +83,7 @@ class KotlinModule private constructor(
8783

8884
val cache = ReflectionCache(reflectionCacheSize)
8985

90-
context.addValueInstantiators(KotlinInstantiators(cache, nullToEmptyCollection, nullToEmptyMap, nullIsSameAsDefault, oldStrictNullChecks))
86+
context.addValueInstantiators(KotlinInstantiators(cache, nullToEmptyCollection, nullToEmptyMap, nullIsSameAsDefault))
9187

9288
if (singletonSupport) {
9389
// [module-kotlin#225]: keep Kotlin singletons as singletons
@@ -102,7 +98,7 @@ class KotlinModule private constructor(
10298
nullToEmptyCollection = nullToEmptyCollection,
10399
nullToEmptyMap = nullToEmptyMap,
104100
nullIsSameAsDefault = nullIsSameAsDefault,
105-
strictNullChecks = newStrictNullChecks,
101+
strictNullChecks = strictNullChecks,
106102
kotlinPropertyNameAsImplicitName = kotlinPropertyNameAsImplicitName
107103
)
108104
)

src/main/kotlin/tools/jackson/module/kotlin/KotlinValueInstantiator.kt

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,13 @@ internal class KotlinValueInstantiator(
2222
private val cache: ReflectionCache,
2323
private val nullToEmptyCollection: Boolean,
2424
private val nullToEmptyMap: Boolean,
25-
private val nullIsSameAsDefault: Boolean,
26-
private val strictNullChecks: Boolean
25+
private val nullIsSameAsDefault: Boolean
2726
) : StdValueInstantiator(src) {
2827
private fun JavaType.requireEmptyValue() =
2928
(nullToEmptyCollection && this.isCollectionLikeType) || (nullToEmptyMap && this.isMapLikeType)
3029

3130
private fun KType.isGenericTypeVar() = javaType is TypeVariable<*>
3231

33-
private fun List<KTypeProjection>.markedNonNullAt(index: Int) = getOrNull(index)?.type?.isMarkedNullable == false
34-
3532
// If the argument is a value class that wraps nullable and non-null,
3633
// and the input is explicit null, the value class is instantiated with null as input.
3734
private fun requireValueClassSpecialNullValue(
@@ -104,35 +101,6 @@ internal class KotlinValueInstantiator(
104101
).wrapWithPath(this.valueClass, pname)
105102
}
106103
}
107-
} else if (strictNullChecks) {
108-
val arguments = paramType.arguments
109-
110-
// To make the behavior the same as deserialization of each element using NullsFailProvider,
111-
// first wrapWithPath with paramVal and key.
112-
val ex = when {
113-
propType.isCollectionLikeType && arguments.markedNonNullAt(0) -> {
114-
(paramVal as Collection<*>).indexOf(null).takeIf { it >= 0 }?.let {
115-
InvalidNullException.from(ctxt, jsonProp.fullName, jsonProp.type)
116-
.wrapWithPath(paramVal, it)
117-
}
118-
}
119-
propType.isMapLikeType && arguments.markedNonNullAt(1) -> {
120-
(paramVal as Map<*, *>).entries.find { (_, v) -> v == null }?.let { (k, _) ->
121-
InvalidNullException.from(ctxt, jsonProp.fullName, jsonProp.type)
122-
.wrapWithPath(paramVal, k.toString())
123-
}
124-
}
125-
propType.isArrayType && arguments.markedNonNullAt(0) -> {
126-
(paramVal as Array<*>).indexOf(null).takeIf { it >= 0 }?.let {
127-
InvalidNullException.from(ctxt, jsonProp.fullName, jsonProp.type)
128-
.wrapWithPath(paramVal, it)
129-
}
130-
}
131-
else -> null
132-
}
133-
134-
// Then, wrapWithPath with this property.
135-
ex?.let { throw it.wrapWithPath(this.valueClass, jsonProp.name) }
136104
}
137105

138106
bucket[paramDef] = paramVal
@@ -151,7 +119,6 @@ internal class KotlinInstantiators(
151119
private val nullToEmptyCollection: Boolean,
152120
private val nullToEmptyMap: Boolean,
153121
private val nullIsSameAsDefault: Boolean,
154-
private val strictNullChecks: Boolean
155122
) : ValueInstantiators.Base() {
156123
override fun modifyValueInstantiator(
157124
deserConfig: DeserializationConfig,
@@ -165,8 +132,7 @@ internal class KotlinInstantiators(
165132
cache,
166133
nullToEmptyCollection,
167134
nullToEmptyMap,
168-
nullIsSameAsDefault,
169-
strictNullChecks
135+
nullIsSameAsDefault
170136
)
171137
} else {
172138
// TODO: return defaultInstantiator and let default method parameters and nullability go unused? or die with exception:

src/test/kotlin/tools/jackson/module/kotlin/KotlinInstantiatorsTest.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ class KotlinInstantiatorsTest {
1313
ReflectionCache(10),
1414
nullToEmptyCollection = false,
1515
nullToEmptyMap = false,
16-
nullIsSameAsDefault = false,
17-
strictNullChecks = false
16+
nullIsSameAsDefault = false
1817
)
1918

2019
@Test

src/test/kotlin/tools/jackson/module/kotlin/MissingKotlinParameterExceptionTest.kt

Lines changed: 0 additions & 21 deletions
This file was deleted.

src/test/kotlin/tools/jackson/module/kotlin/kogeraIntegration/deser/StrictNullChecksTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ import org.junit.jupiter.api.Test
88
import org.junit.jupiter.api.assertThrows
99
import tools.jackson.databind.exc.InvalidNullException
1010
import tools.jackson.databind.json.JsonMapper
11-
import tools.jackson.module.kotlin.KotlinFeature.NewStrictNullChecks
11+
import tools.jackson.module.kotlin.KotlinFeature
1212
import tools.jackson.module.kotlin.kotlinModule
1313
import tools.jackson.module.kotlin.readValue
1414

1515
class StrictNullChecksTest {
1616
private val mapper = JsonMapper.builder()
17-
.addModule(kotlinModule { enable(NewStrictNullChecks) })
17+
.addModule(kotlinModule { enable(KotlinFeature.StrictNullChecks) })
1818
.build()
1919

2020
class ArrayWrapper(val value: Array<Int>)

src/test/kotlin/tools/jackson/module/kotlin/test/StrictNullChecksTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@ import org.junit.jupiter.api.Test
77
import org.junit.jupiter.api.assertThrows
88
import tools.jackson.databind.exc.InvalidNullException
99
import tools.jackson.databind.json.JsonMapper
10-
import tools.jackson.module.kotlin.KotlinFeature.NewStrictNullChecks
10+
import tools.jackson.module.kotlin.KotlinFeature
1111
import tools.jackson.module.kotlin.kotlinModule
1212
import tools.jackson.module.kotlin.readValue
1313
import kotlin.test.assertNull
1414

1515
class StrictNullChecksTest {
1616
private val mapper = JsonMapper.builder()
17-
.addModule(kotlinModule { enable(NewStrictNullChecks) })
17+
.addModule(kotlinModule { enable(KotlinFeature.StrictNullChecks) })
1818
.build()
1919

2020
/** collection tests */

0 commit comments

Comments
 (0)