I found a problem with json deserialization on lists with inherited classes and kotlin. The problem occurs when you define an abstract rest endpoint on kotlin collections. Here's a small example:

abstract class BaseCrudController<Dto : BaseDto> {
    @PostMapping("/saveAll")
    @ResponseBody
    fun saveAsList(@RequestBody dtos: List<Dto>): List<Dto> = listOf()
}

@Controller
@RequestMapping("/api/v1/customer")
class CustomerController() : BaseCrudController<CustomerDto>()

Here's the class to deserialize:

class CustomerDto(var name: String?, var accountNumber: String?) : BaseDto()

abstract class BaseDto {
    var id: Long? = null
    var version: Int = 0
}

The error message is:

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class com.example.basecrudspringrestendpoint.presentation.dto.core.BaseDto]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinition
Exception: Cannot construct instance of `com.example.basecrudspringrestendpoint.presentation.dto.core.BaseDto` (no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
 at [Source: (PushbackInputStream); line: 2, column: 3] (through reference chain: java.util.ArrayList[0])] with root cause

according to a bug ticket in the jackson module, the problem is maybe that spring not passing type resolution context to jackson: https://github.com/FasterXML/jackson-module-kotlin/issues/267

you can find the code for this also here https://github.com/vb-dci/jackson-spring-bug

Comment From: philwebb

Thanks for the report. The HttpMessageConverter is part of Spring Framework so I'll transfer this issue for that team to consider.

Comment From: sdeleuze

Hi, sorry for the delay. I can still reproduce with Spring Boot 3.0.2.

@jhoeller Looks like a potential type caching issue in ResolvableType#forType(Type, TypeProvider, VariableResolver), see attached screenshot. The generic parameter seems wrongly considered as fully resolved due to another entry returned from the cache, making ResolvableType#hasUnresolvableGenerics return false, and skipping the resolution of the generic type from the contextClass.

Screenshot from 2023-02-08 10-18-03

Comment From: sdeleuze

I have a related draft commit, we could maybe introduce related method in ResolvableType to return a type with resolved bounds. Let's try that as part of 6.1 early in the development cycle.

Comment From: sdeleuze

Fixed by f075120675028e396a24deb97e3a32327bbaa479.