Description
Describe the bug
When constructing a type using constructType
and getting its canonical String
representation, a type parameter is added to classes that implement a Collection
type, even if the class itself does not have any type parameters. Trying to read the result back using constructFromCanonical
fails with java.lang.IllegalArgumentException: Cannot create TypeBindings for class kotlin.collections.EmptyList with 1 type parameter: class expects 0
.
Version information
Tested with 2.11.4
and 2.12.2
.
To Reproduce
See the following test written in Kotlin:
class JacksonTypeFactoryTest {
private val objectMapper = ObjectMapper()
@Test
fun `EmptyList type can be converted to canonical string and back`() {
val canonical = objectMapper.typeFactory.constructType(emptyList<String>().javaClass).toCanonical()
println(canonical)
val type = objectMapper.typeFactory.constructFromCanonical(canonical)
println(type)
}
@Test
fun `StringList type can be converted to canonical string and back`() {
val canonical = objectMapper.typeFactory.constructType(StringList::class.java).toCanonical()
println(canonical)
val type = objectMapper.typeFactory.constructFromCanonical(canonical)
println(type)
}
@Test
fun `Non-collection type can be converted to canonical string and back`() {
val canonical = objectMapper.typeFactory.constructType(ConcreteType::class.java).toCanonical()
println(canonical)
val type = objectMapper.typeFactory.constructFromCanonical(canonical)
println(type)
}
class StringList : ArrayList<String>()
open class ParamType<T>
class ConcreteType : ParamType<Int>()
}
The first two tests fail, while the third one succeeds. So it seems to be a problem only with types that extend Collection
.
Expected behavior
TypeFactory
should always produce canonical type names that it can parse again.
Additional context
Although this doesn't seem to be a Kotlin-specific problem, it gains relevance by the fact that Kotlin uses the EmptyList
class to optimize empty lists.
This is similar to #1415 but different in that I'm not using constructCollectionType
here.