Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NPE in RequestBodyService#buildRequestBody when using javadoc #2089

Closed
zman0900 opened this issue Feb 23, 2023 · 7 comments · Fixed by #2111
Closed

NPE in RequestBodyService#buildRequestBody when using javadoc #2089

zman0900 opened this issue Feb 23, 2023 · 7 comments · Fixed by #2111
Labels
bug Something isn't working

Comments

@zman0900
Copy link

Describe the bug
Using springdoc 1.6.13 or 1.6.14, with the javadoc plugin and a controller method that has a parameter annotated with @RequestBody and javadoc for that parameter, accessing Swagger UI shows 500 error and log shows NullPointerException.

The stack trace
java.lang.NullPointerException: Cannot invoke "io.swagger.v3.oas.models.parameters.RequestBody.setDescription(String)" because the return value of "org.springdoc.core.RequestBodyInfo.getRequestBody()" is null
      at org.springdoc.core.RequestBodyService.buildRequestBody(RequestBodyService.java:290)
      at org.springdoc.core.RequestBodyService.calculateRequestBodyInfo(RequestBodyService.java:251)
      at org.springdoc.core.AbstractRequestService.build(AbstractRequestService.java:329)
      at org.springdoc.api.AbstractOpenApiResource.calculatePath(AbstractOpenApiResource.java:503)
      at org.springdoc.api.AbstractOpenApiResource.calculatePath(AbstractOpenApiResource.java:665)
      at org.springdoc.webmvc.api.OpenApiResource.lambda$calculatePath$11(OpenApiResource.java:234)
      at java.base/java.util.Optional.ifPresent(Optional.java:178)
      at org.springdoc.webmvc.api.OpenApiResource.calculatePath(OpenApiResource.java:215)
      at org.springdoc.webmvc.api.OpenApiResource.lambda$getPaths$2(OpenApiResource.java:185)
      at java.base/java.util.Optional.ifPresent(Optional.java:178)
      at org.springdoc.webmvc.api.OpenApiResource.getPaths(OpenApiResource.java:164)
      at org.springdoc.api.AbstractOpenApiResource.getOpenApi(AbstractOpenApiResource.java:364)
      at org.springdoc.webmvc.api.OpenApiResource.openapiJson(OpenApiResource.java:139)
      at org.springdoc.webmvc.api.OpenApiWebMvcResource.openapiJson(OpenApiWebMvcResource.java:116)
      at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
      at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.base/java.lang.reflect.Method.invoke(Method.java:568)
      at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
      at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
      at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
      at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
      at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
      at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
      at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1071)
      at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:964)
      at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
      at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:670)
      at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:779)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
      at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
      at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
      at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
      at org.springframework.cloud.sleuth.instrument.web.servlet.TracingFilter.doFilter(TracingFilter.java:68)
      at org.springframework.cloud.sleuth.autoconfig.instrument.web.TraceWebServletConfiguration$LazyTracingFilter.doFilter(TraceWebServletConfiguration.java:131)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
      at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:177)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
      at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
      at ch.qos.logback.access.tomcat.LogbackValve.invoke(LogbackValve.java:256)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
      at org.springframework.cloud.sleuth.instrument.web.tomcat.TraceValve.invoke(TraceValve.java:103)
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360)
      at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
      at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
      at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:891)
      at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1784)
      at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
      at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
      at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
      at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
      at java.base/java.lang.Thread.run(Thread.java:833)

This seems to happen because org.springdoc.core.RequestBodyService#buildRequestBody is called with non-null requestBody parameter, but with requestBodyInfo parameter containing null for its requestBody field. The only apparent caller of that buildRequestBody method is calculateRequestBodyInfo in the same class, and it does not set requestBody in requestBodyInfo until after making the call.

To Reproduce
Steps to reproduce the behavior:

  • What version of spring-boot you are using? 2.7.9
  • What modules and versions of springdoc-openapi are you using? 1.6.14, with the common, ui, and javadoc modules
@RestController
class Sample {
  /**
   * Sample method.
   * 
   * @param value doc for the request body
   */
  public void something(@RequestBody final String value) {
    // whatever
  }
}

Expected behavior
Expecting Swagger UI to function as it does when using springdoc 1.6.12.

@uc4w6c
Copy link
Collaborator

uc4w6c commented Mar 4, 2023

@zman0900
I didn't have this problem locally. (see: https://github.com/uc4w6c/springdoc-javadoc)
Would it be possible for you to provide a minimal repository to reproduce?

@bnasslahsen bnasslahsen added the invalid This doesn't seem right label Mar 5, 2023
@bnasslahsen
Copy link
Collaborator

@zman0900,

Not reproducible.

@zman0900
Copy link
Author

zman0900 commented Mar 9, 2023

@bnasslahsen please re-open this, it can be reproduced.

Here is a small demo project: https://github.com/zman0900/springdoc-2089-demo

Important part is in the DemoController#update method. When swagger's @RequestBody annotation is used on a parameter without setting the description field, the error in this issue happens. It works if I remove swagger's @RequestBody entirely, but then the swagger UI doesn't document the expected schema. It also works if I add the description field, but then the string from the javadoc must be duplicated. Finally, it works if I downgrade to 1.6.12.

uc4w6c added a commit to uc4w6c/springdoc-openapi that referenced this issue Mar 9, 2023

Verified

This commit was signed with the committer’s verified signature.
iMichka Michka Popoff
…n field of RequestBody is null and there is a javadoc description. Fixes springdoc#2089
uc4w6c added a commit to uc4w6c/springdoc-openapi that referenced this issue Mar 9, 2023
…n field of RequestBody is null and there is a javadoc description. Fixes springdoc#2089
uc4w6c added a commit to uc4w6c/springdoc-openapi that referenced this issue Mar 9, 2023
…n field of RequestBody is null and there is a javadoc description. Fixes springdoc#2089
@bnasslahsen bnasslahsen added bug Something isn't working and removed invalid This doesn't seem right labels Mar 9, 2023
@bnasslahsen
Copy link
Collaborator

@zman0900,

A PR provided by @uc4w6c is now merged for this issue!

@zman0900
Copy link
Author

zman0900 commented Mar 9, 2023

Thanks. Any plan to release another 1.6.x version for those of us still stuck on Spring Boot 2, or will this only be in next 2.x release?

@bnasslahsen
Copy link
Collaborator

both will be released by the end of this week

@zman0900
Copy link
Author

zman0900 commented Mar 9, 2023

Awesome, thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants