最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Can't generate OpenAPI JSON file using springdoc after upgrading Spring Boot to 3.4.1 - Stack Overflow

programmeradmin0浏览0评论

I get the following error when navigating to the url set for our OpenAPI json file after upgrading from Spring Boot 3.3.5 to 3.4.1:

java.lang.NoSuchMethodError: 'void .springframework.web.method.ControllerAdviceBean.<init>(java.lang.Object)'

We're using springdoc version 2.2.0 (artifact id: springdoc-openapi-starter-webmvc-ui) and Java 17 and using ControllerAdvice in one of our modules. We set the following JVM properties: -Dspringdoc.api-docs.groups.enabled=true -Dspringdoc.swagger-ui.enabled=false -Dspringdoc.api-docs.path=/summary/api/openapi.json -Dspringdoc.api-docs.version=OPENAPI_3_1 -Dspringdoc.group-configs[0].group=summary -Dspringdoc.group-configs[0].paths-to-match=/** -Dspringdoc.group-configs[0].packages-to-scan=com.summary -Dspringdoc.group-configs[0].paths-to-include=/** -Dspringdoc.group-configs[0].paths-to-exclude=/*/ws/*

It works again when I revert the Spring Boot version.

This is the class that is failing:

package com.web.controller;

import jakarta.servlet.http.HttpServletRequest;
import .apache.lucene.queryparser.classic.ParseException;
import .slf4j.Logger;
import .slf4j.LoggerFactory;
import .springframework.http.HttpStatus;
import .springframework.web.bind.annotation.ControllerAdvice;
import .springframework.web.bind.annotation.ExceptionHandler;
import .springframework.web.bind.annotation.ResponseStatus;
import .springframework.core.Ordered;
import .springframework.core.annotation.Order;
import .springframework.web.servlet.ModelAndView;


import java.InetAddress;
import java.UnknownHostException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * This is to handle exceptions across all controllers in a uniform way.
 */
@ControllerAdvice
@Order()
public class GlobalControllerExceptionHandler {
    private static final Logger LOGGER                  = LoggerFactory.getLogger(GlobalControllerExceptionHandler.class);
    private static final String MODEL                   = "model";
    
    private PropertiesContainer propertiesContainer = null;

    /**
     * To deal with search failure cases
     * @param request
     * @param exception
     * @return
     */
    @ExceptionHandler(SearchFailedException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ModelAndView handleSearchFailedException(final HttpServletRequest request, final Exception exception) {
        final ModelAndView modelAndView = new ModelAndView("error");
        final Map<String, Object> model = getBaseModel(request, exception);
        // If parsing error,
        if (exception != null && exception.getCause() != null && exception.getCause().getClass().equals(ParseException.class)) {
            model.put("parseError", true);
            model.put("original_query", request.getParameter("query"));
            model.put("title", "Sorry, we can't perform your search request");
        }

        modelAndView.addObject(MODEL, model);
        return modelAndView;
    }

    /**
     * To deal with other exceptions
     * @param request
     * @param exception
     * @return
     */
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ModelAndView handleException(final HttpServletRequest request, final Exception exception) {
        final ModelAndView modelAndView = new ModelAndView("error");
        final Map<String, Object> model = getBaseModel(request, exception);
        model.put("title", "Something has gone wrong with our web server");
        modelAndView.addObject(MODEL, model);
        return modelAndView;
    }

    /**
     * Return a base map with given request and exception
     * @param request
     * @param exception
     * @return
     */
    protected Map<String, Object> getBaseModel(final HttpServletRequest request, final Exception exception) {
        final Map<String, Object> model = new HashMap<>();

        setException(model, exception);
        setTimeStamp(model);
        setLocalHost(model);
        setAppVersion(model);

        return model;
    }

    protected static void setException(final Map<String, Object> model, final Exception exception) {
        model.put("exception", exception);
    }

    protected static void setLocalHost(final Map<String, Object> model) {
        try {
            model.put("server", getCurrentHostname());
        } catch (final UnknownHostException e) {
            LOGGER.warn(ExceptionMessageContainer.cannotGetLocalHostName(), e);
        }
    }

    protected static void setTimeStamp(final Map<String, Object> model) {
        model.put("timestamp", new Date(System.currentTimeMillis()).toString());
    }

    protected static String getCurrentHostname() throws UnknownHostException {
        return InetAddress.getLocalHost().getHostName();
    }

    protected PropertiesContainer getPropertiesContainer() {
        if (propertiesContainer == null) {
            propertiesContainer = PropertiesHelper.getPropertiesContainer();
        }
        return propertiesContainer;
    }

    protected void setAppVersion(final Map<String, Object> model) {

        if (MetaInfUtil.getAppVersion() != null) {
            model.put("appversion", MetaInfUtil.getAppVersion());
        }
        else {
            model.put("appversion", System.currentTimeMillis());
        }

    }
}

And the full stacktrace:

2025-02-04 11:47:06,530 DEBUG [http-nio-8080-exec-2] o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - Using @ExceptionHandler com.web.controller.GlobalControllerExceptionHandler#handleException(HttpServletRequest, Exception)
jakarta.servlet.ServletException: Handler dispatch failed: java.lang.NoSuchMethodError: 'void .springframework.web.method.ControllerAdviceBean.<init>(java.lang.Object)'
    at .springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1103)
    at .springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:978)
    at .springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
    at .springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
    at .springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
    at .apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195)
    at .apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
    at .apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
    at .apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
    at .apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
    at .springframework.web.filter.AbstractRequestLoggingFilter.doFilterInternal(AbstractRequestLoggingFilter.java:289)
    at .springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
    at .apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
    at .apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
    at .springframework.web.filter.ServerHttpObservationFilter.doFilterInternal(ServerHttpObservationFilter.java:114)
    at .springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
    at .apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
    at .apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
    at .springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
    at .springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
    at .apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
    at .apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
    at .apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
    at .apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
    at .apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483)
    at .apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115)
    at .apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
    at .apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at .apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:663)
    at .apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344)
    at .apache.coyote.http11.Http11Processor.service(Http11Processor.java:397)
    at .apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
    at .apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:905)
    at .apache.tomcat.util.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741)
    at .apache.tomcat.util.SocketProcessorBase.run(SocketProcessorBase.java:52)
    at .apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190)
    at .apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
    at .apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
    at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.NoSuchMethodError: 'void .springframework.web.method.ControllerAdviceBean.<init>(java.lang.Object)'
    at .springdoc.core.service.GenericResponseService.lambda$getGenericMapResponse$8(GenericResponseService.java:700)
    at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:178)
    at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:992)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:575)
    at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:260)
    at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:616)
    at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:622)
    at java.base/java.util.stream.ReferencePipeline.toList(ReferencePipeline.java:627)
    at .springdoc.core.service.GenericResponseService.getGenericMapResponse(GenericResponseService.java:702)
    at .springdoc.core.service.GenericResponseService.build(GenericResponseService.java:245)
    at .springdoc.api.AbstractOpenApiResource.calculatePath(AbstractOpenApiResource.java:496)
    at .springdoc.api.AbstractOpenApiResource.calculatePath(AbstractOpenApiResource.java:673)
    at .springdoc.webmvc.api.OpenApiResource.lambda$calculatePath$11(OpenApiResource.java:219)
    at java.base/java.util.Optional.ifPresent(Optional.java:178)
    at .springdoc.webmvc.api.OpenApiResource.calculatePath(OpenApiResource.java:200)
    at .springdoc.webmvc.api.OpenApiResource.lambda$getPaths$2(OpenApiResource.java:170)
    at java.base/java.util.Optional.ifPresent(Optional.java:178)
    at .springdoc.webmvc.api.OpenApiResource.getPaths(OpenApiResource.java:149)
    at .springdoc.api.AbstractOpenApiResource.getOpenApi(AbstractOpenApiResource.java:350)
    at .springdoc.webmvc.api.OpenApiResource.openapiJson(OpenApiResource.java:124)
    at .springdoc.webmvc.api.OpenApiWebMvcResource.openapiJson(OpenApiWebMvcResource.java:111)
    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 .springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:257)
    at .springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:190)
    at .springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)
    at .springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:986)
    at .springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:891)
    at .springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at .springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1088)
    ... 40 more

I've tried setting the order precedence to high as seen in another post, since there is another ControllerAdvice in the same module, and that didn't work. I also tried changing @ControllerAdvice to @RestControllerAdvice, also with no effect. The other openapi.json in our app, which is located in the root application, does work.

发布评论

评论列表(0)

  1. 暂无评论
ok 不同模板 switch ($forum['model']) { /*case '0': include _include(APP_PATH . 'view/htm/read.htm'); break;*/ default: include _include(theme_load('read', $fid)); break; } } break; case '10': // 主题外链 / thread external link http_location(htmlspecialchars_decode(trim($thread['description']))); break; case '11': // 单页 / single page $attachlist = array(); $imagelist = array(); $thread['filelist'] = array(); $threadlist = NULL; $thread['files'] > 0 and list($attachlist, $imagelist, $thread['filelist']) = well_attach_find_by_tid($tid); $data = data_read_cache($tid); empty($data) and message(-1, lang('data_malformation')); $tidlist = $forum['threads'] ? page_find_by_fid($fid, $page, $pagesize) : NULL; if ($tidlist) { $tidarr = arrlist_values($tidlist, 'tid'); $threadlist = well_thread_find($tidarr, $pagesize); // 按之前tidlist排序 $threadlist = array2_sort_key($threadlist, $tidlist, 'tid'); } $allowpost = forum_access_user($fid, $gid, 'allowpost'); $allowupdate = forum_access_mod($fid, $gid, 'allowupdate'); $allowdelete = forum_access_mod($fid, $gid, 'allowdelete'); $access = array('allowpost' => $allowpost, 'allowupdate' => $allowupdate, 'allowdelete' => $allowdelete); $header['title'] = $thread['subject']; $header['mobile_link'] = $thread['url']; $header['keywords'] = $thread['keyword'] ? $thread['keyword'] : $thread['subject']; $header['description'] = $thread['description'] ? $thread['description'] : $thread['brief']; $_SESSION['fid'] = $fid; if ($ajax) { empty($conf['api_on']) and message(0, lang('closed')); $apilist['header'] = $header; $apilist['extra'] = $extra; $apilist['access'] = $access; $apilist['thread'] = well_thread_safe_info($thread); $apilist['thread_data'] = $data; $apilist['forum'] = $forum; $apilist['imagelist'] = $imagelist; $apilist['filelist'] = $thread['filelist']; $apilist['threadlist'] = $threadlist; message(0, $apilist); } else { include _include(theme_load('single_page', $fid)); } break; default: message(-1, lang('data_malformation')); break; } ?>