You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Describe the bug
null values can still sneak into a deserialized collection-of-non-nullables if you use the inline-reified ObjectMapper.readValue extension methods, among others.
To Reproduce
val mapper = ObjectMapper().registerModule(KotlinModule(strictNullChecks = true))
val tf = mapper.typeFactory // less typing below
val json = "[1, 2, 3, null]"
// Every one of the following succeed
val l1 = mapper.readValue<List<Int>>(json) // This is the inline reified extension.
val l2 = mapper.readValue<List<Int>>(json, jacksonTypeRef<List<Int>>()) // This is what the inline reified really calls.
val l3 = mapper.readValue<List<Int>>(json, tf.constructCollectionLikeType(List::class.java, tf.constructType(jacksonTypeRef<Int>()))
val l4 = mapper.readValue<List<Int>>(json, tf.constructCollectionLikeType(List::class.java, Int::class.java))
val l5 = mapper.readValue<List<Int>>(json, tf.constructCollectionType(List::class.java, tf.constructType(jacksonTypeRef<Int>()))
val l6 = mapper.readValue<List<Int>>(json, tf.constructCollectionType(List::class.java, Int::class.java))
println(l1) // [1, 2, 3, null]
println(l2) // [1, 2, 3, null]
println(l3) // [1, 2, 3, null]
println(l4) // [1, 2, 3, 0]
println(l5) // [1, 2, 3, null]
println(l6) // [1, 2, 3, 0]
Expected behavior
All of the above mapper calls should fail
NOTE: The ones that use Int::class.java (l4 and l6) do fail if I also enable DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES. But, in that case, it doesn't even matter if strictNullChecks is enabled or not.
In fact, none of the above results seem to care if I enable strictNullChecks.
This is because KotlinValueInstantiator.createFromObjectWith(), where strictNullChecks is enforced, isn't called for any of these calls that create a collection without an enclosing object, due to jackson-databind's design. The first test in this gist demonstrates strictNullChecks with an enclosing object, in which case an exception is thrown:
com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException: Instantiation of kotlin.Int collection failed for JSON property list due to null value in a collection that does not allow null values
at [Source: (String)"{"list": [1, null]}"; line: 1, column: 19] (through reference chain: com.fasterxml.jackson.module.kotlin.test.github.failing.GitHub479Test$fullObject$Data["list"])
There might be some other method of ValueInstantiator that the Kotlin module could override to enforce non-nullability for such collection types.
Describe the bug
null values can still sneak into a deserialized collection-of-non-nullables if you use the inline-reified ObjectMapper.readValue extension methods, among others.
To Reproduce
Expected behavior
All of the above mapper calls should fail
NOTE: The ones that use Int::class.java (
l4
andl6
) do fail if I also enableDeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES
. But, in that case, it doesn't even matter ifstrictNullChecks
is enabled or not.In fact, none of the above results seem to care if I enable
strictNullChecks
.Versions
Kotlin: 1.4.something
Jackson-module-kotlin: 2.12.3+
Jackson-databind: 2.12.3+
Additional context
I have no idea why this doesn't seem to work for me. I must be doing something wrong, but I don't know what.
The text was updated successfully, but these errors were encountered: