Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't figure out strictNullCheck option #479

Closed
ragnese opened this issue Jul 22, 2021 · 2 comments
Closed

Can't figure out strictNullCheck option #479

ragnese opened this issue Jul 22, 2021 · 2 comments
Labels

Comments

@ragnese
Copy link

ragnese commented Jul 22, 2021

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.

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.

@ragnese ragnese added the bug label Jul 22, 2021
@dinomite
Copy link
Member

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.

@k163377
Copy link
Contributor

k163377 commented Mar 3, 2023

This issue is closed as a duplicate of #399.

@k163377 k163377 closed this as completed Mar 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants