Description
Describe the bug
I wanted to upgrade from Springdoc 1.3.9 on Spring Boot 2.3.1 to Springdoc 1.4.7 on Spring Boot 2.3.4
On opening the swagger-ui, I get the following exception:
java.lang.NullPointerException: null at org.springframework.core.annotation.AnnotationsScanner.getDeclaredAnnotations(AnnotationsScanner.java:459) at org.springframework.core.annotation.AnnotationsScanner.isKnownEmpty(AnnotationsScanner.java:492) at org.springframework.core.annotation.TypeMappedAnnotations.from(TypeMappedAnnotations.java:251) at org.springframework.core.annotation.MergedAnnotations.from(MergedAnnotations.java:351) at org.springframework.core.annotation.MergedAnnotations.from(MergedAnnotations.java:330) at org.springframework.core.annotation.AnnotatedElementUtils.findAnnotations(AnnotatedElementUtils.java:764) at org.springframework.core.annotation.AnnotatedElementUtils.findMergedAnnotation(AnnotatedElementUtils.java:632) at org.springdoc.core.AbstractRequestBuilder.build(AbstractRequestBuilder.java:243) at org.springdoc.api.AbstractOpenApiResource.calculatePath(AbstractOpenApiResource.java:372) at org.springdoc.api.AbstractOpenApiResource.calculatePath(AbstractOpenApiResource.java:505) at org.springdoc.webmvc.api.OpenApiResource.calculatePath(OpenApiResource.java:259) at org.springdoc.webmvc.api.OpenApiResource.getPaths(OpenApiResource.java:210) at org.springdoc.api.AbstractOpenApiResource.getOpenApi(AbstractOpenApiResource.java:268) at org.springdoc.webmvc.api.OpenApiResource.openapiJson(OpenApiResource.java:179) at org.springdoc.webmvc.api.MultipleOpenApiResource.openapiJson(MultipleOpenApiResource.java:200) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) …
I don't get an exception when I remove my @ParameterObject-annotations from my code.
To Reproduce
Steps to reproduce the behavior:
-
What version of spring-boot you are using? 2.3.4
-
What modules and versions of springdoc-openapi are you using?
springdoc-openapi-ui 1.4.7
springdoc-openapi-data-rest 1.4.7
springdoc-openapi-security 1.4.7 -
Provide with a sample code (HelloController) or Test that reproduces the problem
The problem is easily reproducible with the following sample code:
Controller:
@Validated
@RestController
@RequestMapping(value = {VERSION + "/helloWorld", "latest/helloWorld"}, produces = MediaType.APPLICATION_JSON_VALUE)
public class HelloController {
@Operation(summary = "Example endpoint")
@GetMapping("/helloWorld")
public HelloWorldResponseModel helloWorld(@Valid @ParameterObject HelloWorldModel helloWorldModel, HttpServletRequest request) {
return new HelloWorldResponseModel();
}
}
The request parameter object "HelloWorldModel":
import io.swagger.v3.oas.annotations.Parameter;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.time.LocalDate;
public class HelloWorldModel {
@Parameter(description = "Description for abc", example = "def")
@NotBlank
private String abc;
@Parameter(description = "Description of this date", example = "2020-10-25")
@NotNull
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
private LocalDate thisDate;
public String getAbc() {
return abc;
}
public void setAbc(String abc) {
this.abc = abc;
}
public LocalDate getThisDate() {
return thisDate;
}
public void setThisDate(LocalDate thisDate) {
this.thisDate = thisDate;
}
}
The Application class:
// ...
public static final String VERSION = "v1";
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public GroupedOpenApi v1() {
return GroupedOpenApi.builder()
.group(VERSION)
.pathsToMatch("/" + VERSION + "/**")
.build();
}
@Bean
public GroupedOpenApi latest() {
return GroupedOpenApi.builder()
.group("latest")
.pathsToMatch("/latest/**")
.build();
}
In case it matters, application.properties I used:
springdoc.swagger-ui.path=/doc
springdoc.paths-to-exclude=/
springdoc.api-docs.path=/api-docs