My model consists of AutoValue classes. This means the classes are abstract and backed by hidden concrete classes. I created deserializers for those classes, but when I try to call the webservice with a class, I'm greeted with a exception because my classes are abstract.

Failed to instantiate [project.Person]: Is it an abstract class?; nested exception is java.lang.InstantiationException

The relevant stack trace is this:

    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:212) ~[spring-beans-5.3.3.jar:5.3.3]
    at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.constructAttribute(ModelAttributeMethodProcessor.java:242) ~[spring-web-5.3.3.jar:5.3.3]
    at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.createAttribute(ModelAttributeMethodProcessor.java:215) ~[spring-web-5.3.3.jar:5.3.3]
    at org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor.createAttribute(ServletModelAttributeMethodProcessor.java:85) ~[spring-webmvc-5.3.3.jar:5.3.3]
    at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:142) ~[spring-web-5.3.3.jar:5.3.3]
    at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121) ~[spring-web-5.3.3.jar:5.3.3]
    at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:170) ~[spring-web-5.3.3.jar:5.3.3]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) ~[spring-web-5.3.3.jar:5.3.3]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.3.3.jar:5.3.3]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894) ~[spring-webmvc-5.3.3.jar:5.3.3]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.3.jar:5.3.3]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.3.jar:5.3.3]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1060) ~[spring-webmvc-5.3.3.jar:5.3.3]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:962) ~[spring-webmvc-5.3.3.jar:5.3.3]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.3.jar:5.3.3]
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.3.3.jar:5.3.3]

I'm using Spring Boot 2.4.2 with a @RestController.

I configured a Serializer class annotated with @JsonComponent and both a (Jackson) JsonSerializer and a JsonDeserializer nested in it. The serializer works like a charm, eg. in a GET method. But having an abstract class as a method parameter, such as in @PostMapping add(Book book) { ... } where Book is the abstract class, fails with the stacktrace above.

When I debug, at no time is my deserializer used.

I believe that if I provide a Jackson deserializer, Spring shouldn't try to instanciate the class and let Jackson deserialize it instead.

Comment From: wilkinsona

ServletModelAttributeMethodProcessor is used to bind servlet request parameters to a Java object. If you want to bind a request body to a Java object the method parameter should be annotated with @RequestBody. The binding will then be performed via HTTP message conversion and will use Jackson for application/json payloads.

Comment From: ogregoire

@wilkinsona Yes, that's it. Sorry to have wasted your time!