Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,12 @@
<!-- removed -->
<exclude>com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException</exclude>
<!-- internal -->
<exclude>
com.fasterxml.jackson.module.kotlin.KotlinInstantiators#KotlinInstantiators(com.fasterxml.jackson.module.kotlin.ReflectionCache,boolean,boolean,boolean,boolean)
</exclude>
<exclude>
com.fasterxml.jackson.module.kotlin.KotlinValueInstantiator#KotlinValueInstantiator(com.fasterxml.jackson.databind.deser.std.StdValueInstantiator,com.fasterxml.jackson.module.kotlin.ReflectionCache,boolean,boolean,boolean,boolean)
</exclude>
</excludes>
</parameter>
</configuration>
Expand Down
1 change: 1 addition & 0 deletions release-notes/CREDITS-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Contributors:
# 2.21.0 (not yet released)

WrongWrong (@k163377)
* #1042: Remove old StrictNullChecks
* #1041: Remove MissingKotlinParameterException
* #1039: Update settings for 2.20

Expand Down
2 changes: 2 additions & 0 deletions release-notes/VERSION-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ Co-maintainers:

2.21.0 (not yet released)

#1042: The old StrictNullChecks backend has been removed.
This improves the throughput of deserialization slightly.
#1041: The deprecated MissingKotlinParameterException has been removed.
#1039: Kotlin has been upgraded to 2.1.x.

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

/**
Expand Down Expand Up @@ -80,15 +79,15 @@ enum class KotlinFeature(internal val enabledByDefault: Boolean) {
* Internally, it will be the same as if [JsonSetter] (contentNulls = FAIL) had been granted.
* Benchmarks show that it can check for illegal nulls with throughput nearly identical to the default (see [jackson-module-kotlin#719]).
*
* Note that in the new backend, the exception thrown has changed from [MissingKotlinParameterException] to [InvalidNullException].
* The message will be changed accordingly.
* Since 2.19, the base class of [MissingKotlinParameterException] has also been changed to [InvalidNullException],
* so be careful when catching it.
*
* This is a temporary option for a phased backend migration,
* which will eventually be merged into [StrictNullChecks].
* Also, specifying both this and [StrictNullChecks] is not permitted.
*/
@Deprecated(
level = DeprecationLevel.WARNING,
message = "This option will be merged into StrictNullChecks in 2.23.",
replaceWith = ReplaceWith("StrictNullChecks")
)
NewStrictNullChecks(enabledByDefault = false);

internal val bitSet: BitSet = (1 shl ordinal).toBitSet()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,10 @@ class KotlinModule private constructor(
val nullToEmptyMap: Boolean = NullToEmptyMap.enabledByDefault,
val nullIsSameAsDefault: Boolean = NullIsSameAsDefault.enabledByDefault,
val singletonSupport: Boolean = SingletonSupport.enabledByDefault,
@Suppress("DEPRECATION_ERROR")
strictNullChecks: Boolean = StrictNullChecks.enabledByDefault,
val kotlinPropertyNameAsImplicitName: Boolean = KotlinPropertyNameAsImplicitName.enabledByDefault,
val useJavaDurationConversion: Boolean = UseJavaDurationConversion.enabledByDefault,
private val newStrictNullChecks: Boolean = NewStrictNullChecks.enabledByDefault,
newStrictNullChecks: Boolean = NewStrictNullChecks.enabledByDefault,
) : SimpleModule(KotlinModule::class.java.name, PackageVersion.VERSION) {
/*
* Prior to 2.18, an older Enum called SingletonSupport was used to manage feature.
Expand All @@ -67,8 +66,6 @@ class KotlinModule private constructor(
)
val enabledSingletonSupport: Boolean get() = singletonSupport

private val oldStrictNullChecks: Boolean = strictNullChecks

// To reduce the amount of destructive changes, no properties will be added to the public.
val strictNullChecks: Boolean = if (strictNullChecks) {
if (newStrictNullChecks) {
Expand Down Expand Up @@ -113,7 +110,7 @@ class KotlinModule private constructor(

val cache = ReflectionCache(reflectionCacheSize)

context.addValueInstantiators(KotlinInstantiators(cache, nullToEmptyCollection, nullToEmptyMap, nullIsSameAsDefault, oldStrictNullChecks))
context.addValueInstantiators(KotlinInstantiators(cache, nullToEmptyCollection, nullToEmptyMap, nullIsSameAsDefault))

if (singletonSupport) {
context.addBeanDeserializerModifier(KotlinBeanDeserializerModifier)
Expand All @@ -128,7 +125,7 @@ class KotlinModule private constructor(
useJavaDurationConversion
))
context.appendAnnotationIntrospector(
KotlinNamesAnnotationIntrospector(cache, newStrictNullChecks, kotlinPropertyNameAsImplicitName)
KotlinNamesAnnotationIntrospector(cache, strictNullChecks, kotlinPropertyNameAsImplicitName)
)

context.addDeserializers(KotlinDeserializers(cache, useJavaDurationConversion))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,13 @@ internal class KotlinValueInstantiator(
private val cache: ReflectionCache,
private val nullToEmptyCollection: Boolean,
private val nullToEmptyMap: Boolean,
private val nullIsSameAsDefault: Boolean,
private val strictNullChecks: Boolean
private val nullIsSameAsDefault: Boolean
) : StdValueInstantiator(src) {
private fun JavaType.requireEmptyValue() =
(nullToEmptyCollection && this.isCollectionLikeType) || (nullToEmptyMap && this.isMapLikeType)

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

private fun List<KTypeProjection>.markedNonNullAt(index: Int) = getOrNull(index)?.type?.isMarkedNullable == false

// If the argument is a value class that wraps nullable and non-null,
// and the input is explicit null, the value class is instantiated with null as input.
private fun requireValueClassSpecialNullValue(
Expand Down Expand Up @@ -104,35 +101,6 @@ internal class KotlinValueInstantiator(
).wrapWithPath(this.valueClass, pname)
}
}
} else if (strictNullChecks) {
val arguments = paramType.arguments

// To make the behavior the same as deserialization of each element using NullsFailProvider,
// first wrapWithPath with paramVal and key.
val ex = when {
propType.isCollectionLikeType && arguments.markedNonNullAt(0) -> {
(paramVal as Collection<*>).indexOf(null).takeIf { it >= 0 }?.let {
InvalidNullException.from(ctxt, jsonProp.fullName, jsonProp.type)
.wrapWithPath(paramVal, it)
}
}
propType.isMapLikeType && arguments.markedNonNullAt(1) -> {
(paramVal as Map<*, *>).entries.find { (_, v) -> v == null }?.let { (k, _) ->
InvalidNullException.from(ctxt, jsonProp.fullName, jsonProp.type)
.wrapWithPath(paramVal, k.toString())
}
}
propType.isArrayType && arguments.markedNonNullAt(0) -> {
(paramVal as Array<*>).indexOf(null).takeIf { it >= 0 }?.let {
InvalidNullException.from(ctxt, jsonProp.fullName, jsonProp.type)
.wrapWithPath(paramVal, it)
}
}
else -> null
}

// Then, wrapWithPath with this property.
ex?.let { throw it.wrapWithPath(this.valueClass, jsonProp.name) }
}

bucket[paramDef] = paramVal
Expand All @@ -151,7 +119,6 @@ internal class KotlinInstantiators(
private val nullToEmptyCollection: Boolean,
private val nullToEmptyMap: Boolean,
private val nullIsSameAsDefault: Boolean,
private val strictNullChecks: Boolean
) : ValueInstantiators {
override fun findValueInstantiator(
deserConfig: DeserializationConfig,
Expand All @@ -165,8 +132,7 @@ internal class KotlinInstantiators(
cache,
nullToEmptyCollection,
nullToEmptyMap,
nullIsSameAsDefault,
strictNullChecks
nullIsSameAsDefault
)
} else {
// TODO: return defaultInstantiator and let default method parameters and nullability go unused? or die with exception:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ class KotlinInstantiatorsTest {
ReflectionCache(10),
nullToEmptyCollection = false,
nullToEmptyMap = false,
nullIsSameAsDefault = false,
strictNullChecks = false
nullIsSameAsDefault = false
)

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class StrictNullChecksTest {
val mapper: ObjectMapper = ObjectMapper()
.registerModule(
KotlinModule.Builder()
.enable(KotlinFeature.NewStrictNullChecks)
.enable(KotlinFeature.StrictNullChecks)
.build()
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package com.fasterxml.jackson.module.kotlin.test

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.exc.InvalidNullException
import com.fasterxml.jackson.module.kotlin.KotlinFeature.NewStrictNullChecks
import com.fasterxml.jackson.module.kotlin.KotlinFeature
import com.fasterxml.jackson.module.kotlin.kotlinModule
import com.fasterxml.jackson.module.kotlin.readValue
import org.junit.jupiter.api.Assertions.assertArrayEquals
Expand All @@ -13,7 +13,7 @@ import org.junit.jupiter.api.assertThrows
import kotlin.test.assertNull

class StrictNullChecksTest {
private val mapper = ObjectMapper().registerModule(kotlinModule { enable(NewStrictNullChecks) })
private val mapper = ObjectMapper().registerModule(kotlinModule { enable(KotlinFeature.StrictNullChecks) })

/** collection tests */

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class GitHub757 {
@Test
fun test() {
val kotlinModule = KotlinModule.Builder()
.enable(KotlinFeature.NewStrictNullChecks)
.enable(KotlinFeature.StrictNullChecks)
.build()
val mapper = JsonMapper.builder()
.addModule(kotlinModule)
Expand Down
Loading