Skip to content

TypeFactory cannot convert Collection sub-type without type parameters to canonical form and back #3108

Closed
@lbilger

Description

@lbilger

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions