Springboot 2.6.0 / Spring fox 3 - 无法启动 bean 'documentationPluginsBootstrapper'

Posted

技术标签:

【中文标题】Springboot 2.6.0 / Spring fox 3 - 无法启动 bean \'documentationPluginsBootstrapper\'【英文标题】:Spring Boot 2.6.0 / Spring fox 3 - Failed to start bean 'documentationPluginsBootstrapper'Springboot 2.6.0 / Spring fox 3 - 无法启动 bean 'documentationPluginsBootstrapper' 【发布时间】:2021-12-30 08:27:48 【问题描述】:

我正在尝试使用 Open Jdk 15、Springboot 2.6.0、Springfox 3 启动 Springboot 项目。 我们正在开发一个项目,将 Netty 替换为 Web 服务器并使用 Jetty,因为我们不需要非阻塞环境。 在代码中我们主要依赖 Reactor API(Flux、Mono),所以我们无法移除 org.springframework.boot:spring-boot-starter-webflux 依赖。

我复制了我们在一个新项目中遇到的问题。:https://github.com/jvacaq/spring-fox。随便抓个副本。

我发现我们的 build.gradle 文件中的这些行是问题的根源。

compile("org.springframework.boot:spring-boot-starter-web") 
   exclude module: "spring-boot-starter-tomcat"

compile("org.springframework.boot:spring-boot-starter-jetty")

这里是 build.gradle 文件

plugins 
    id 'org.springframework.boot' version '2.6.0'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'


group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

repositories 
    mavenCentral()


dependencies 
    compile("org.springframework.boot:spring-boot-starter-web") 
        exclude module: "spring-boot-starter-tomcat"
    
    compile("org.springframework.boot:spring-boot-starter-jetty")
    implementation 'org.springframework.boot:spring-boot-starter-webflux'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'io.projectreactor:reactor-test'
    implementation "io.springfox:springfox-boot-starter:3.0.0"


test 
    useJUnitPlatform()


我发出了命令gradle clean bootrun。结果是这个错误:有没有人知道如何解决它?

 gradle clean bootrun                                                                                                                                                                                                               

> Task :bootRun FAILED

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.6.0)

2021-11-19 09:41:06.665  INFO 16666 --- [           main] c.e.springfox.SpringFoxApplication       : Starting SpringFoxApplication using Java 15.0.2 on advance-Inspiron-5379 with PID 16666 (/home/advance/projects/spring-fox/build/classes/java/main started by advance in /home/advance/projects/spring-fox)
2021-11-19 09:41:06.666  INFO 16666 --- [           main] c.e.springfox.SpringFoxApplication       : No active profile set, falling back to default profiles: default
2021-11-19 09:41:07.294  INFO 16666 --- [           main] org.eclipse.jetty.util.log               : Logging initialized @1132ms to org.eclipse.jetty.util.log.Slf4jLog
2021-11-19 09:41:07.396  INFO 16666 --- [           main] o.s.b.w.e.j.JettyServletWebServerFactory : Server initialized with port: 8080
2021-11-19 09:41:07.398  INFO 16666 --- [           main] org.eclipse.jetty.server.Server          : jetty-9.4.44.v20210927; built: 2021-09-27T23:02:44.612Z; git: 8da83308eeca865e495e53ef315a249d63ba9332; jvm 15.0.2+7-27
2021-11-19 09:41:07.417  INFO 16666 --- [           main] o.e.j.s.h.ContextHandler.application     : Initializing Spring embedded WebApplicationContext
2021-11-19 09:41:07.417  INFO 16666 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 713 ms
2021-11-19 09:41:07.474  INFO 16666 --- [           main] org.eclipse.jetty.server.session         : DefaultSessionIdManager workerName=node0
2021-11-19 09:41:07.474  INFO 16666 --- [           main] org.eclipse.jetty.server.session         : No SessionScavenger set, using defaults
2021-11-19 09:41:07.475  INFO 16666 --- [           main] org.eclipse.jetty.server.session         : node0 Scavenging every 660000ms
2021-11-19 09:41:07.480  INFO 16666 --- [           main] o.e.jetty.server.handler.ContextHandler  : Started o.s.b.w.e.j.JettyEmbeddedWebAppContext@6aa3bfcapplication,/,[file:///tmp/jetty-docbase.8080.2024342829220941812/, jar:file:/home/advance/.gradle/caches/modules-2/files-2.1/io.springfox/springfox-swagger-ui/3.0.0/1e665fbe22148f7c36fa8a08e515a0047cd4390b/springfox-swagger-ui-3.0.0.jar!/META-INF/resources],AVAILABLE
2021-11-19 09:41:07.480  INFO 16666 --- [           main] org.eclipse.jetty.server.Server          : Started @1318ms
2021-11-19 09:41:07.920  INFO 16666 --- [           main] o.e.j.s.h.ContextHandler.application     : Initializing Spring DispatcherServlet 'dispatcherServlet'
2021-11-19 09:41:07.920  INFO 16666 --- [           main] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2021-11-19 09:41:07.921  INFO 16666 --- [           main] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
2021-11-19 09:41:07.931  INFO 16666 --- [           main] o.e.jetty.server.AbstractConnector       : Started ServerConnector@2643d762HTTP/1.1, (http/1.1)0.0.0.0:8080
2021-11-19 09:41:07.932  INFO 16666 --- [           main] o.s.b.web.embedded.jetty.JettyWebServer  : Jetty started on port(s) 8080 (http/1.1) with context path '/'
2021-11-19 09:41:07.934  WARN 16666 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException: Cannot invoke "org.springframework.web.servlet.mvc.condition.PatternsRequestCondition.getPatterns()" because "this.condition" is null
2021-11-19 09:41:07.949  INFO 16666 --- [           main] o.e.jetty.server.AbstractConnector       : Stopped ServerConnector@2643d762HTTP/1.1, (http/1.1)0.0.0.0:8080
2021-11-19 09:41:07.950  INFO 16666 --- [           main] org.eclipse.jetty.server.session         : node0 Stopped scavenging
2021-11-19 09:41:07.951  INFO 16666 --- [           main] o.e.j.s.h.ContextHandler.application     : Destroying Spring FrameworkServlet 'dispatcherServlet'
2021-11-19 09:41:07.951  INFO 16666 --- [           main] o.e.jetty.server.handler.ContextHandler  : Stopped o.s.b.w.e.j.JettyEmbeddedWebAppContext@6aa3bfcapplication,/,[file:///tmp/jetty-docbase.8080.2024342829220941812/, jar:file:/home/advance/.gradle/caches/modules-2/files-2.1/io.springfox/springfox-swagger-ui/3.0.0/1e665fbe22148f7c36fa8a08e515a0047cd4390b/springfox-swagger-ui-3.0.0.jar!/META-INF/resources],STOPPED
2021-11-19 09:41:07.958  INFO 16666 --- [           main] ConditionEvaluationReportLoggingListener : 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-11-19 09:41:07.970 ERROR 16666 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.context.ApplicationContextException: Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException: Cannot invoke "org.springframework.web.servlet.mvc.condition.PatternsRequestCondition.getPatterns()" because "this.condition" is null
        at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:181) ~[spring-context-5.3.13.jar:5.3.13]
        at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:54) ~[spring-context-5.3.13.jar:5.3.13]
        at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:356) ~[spring-context-5.3.13.jar:5.3.13]
        at java.base/java.lang.Iterable.forEach(Iterable.java:75) ~[na:na]
        at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:155) ~[spring-context-5.3.13.jar:5.3.13]
        at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:123) ~[spring-context-5.3.13.jar:5.3.13]
        at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:935) ~[spring-context-5.3.13.jar:5.3.13]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:586) ~[spring-context-5.3.13.jar:5.3.13]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) ~[spring-boot-2.6.0.jar:2.6.0]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730) ~[spring-boot-2.6.0.jar:2.6.0]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:412) ~[spring-boot-2.6.0.jar:2.6.0]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:302) ~[spring-boot-2.6.0.jar:2.6.0]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301) ~[spring-boot-2.6.0.jar:2.6.0]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1290) ~[spring-boot-2.6.0.jar:2.6.0]
        at com.example.springfox.SpringFoxApplication.main(SpringFoxApplication.java:10) ~[main/:na]
Caused by: java.lang.NullPointerException: Cannot invoke "org.springframework.web.servlet.mvc.condition.PatternsRequestCondition.getPatterns()" because "this.condition" is null
        at springfox.documentation.spring.web.WebMvcPatternsRequestConditionWrapper.getPatterns(WebMvcPatternsRequestConditionWrapper.java:56) ~[springfox-spring-webmvc-3.0.0.jar:3.0.0]
        at springfox.documentation.RequestHandler.sortedPaths(RequestHandler.java:113) ~[springfox-core-3.0.0.jar:3.0.0]
        at springfox.documentation.spi.service.contexts.Orderings.lambda$byPatternsCondition$3(Orderings.java:89) ~[springfox-spi-3.0.0.jar:3.0.0]
        at java.base/java.util.Comparator.lambda$comparing$77a9974f$1(Comparator.java:469) ~[na:na]
        at java.base/java.util.TimSort.countRunAndMakeAscending(TimSort.java:355) ~[na:na]
        at java.base/java.util.TimSort.sort(TimSort.java:220) ~[na:na]
        at java.base/java.util.Arrays.sort(Arrays.java:1306) ~[na:na]
        at java.base/java.util.ArrayList.sort(ArrayList.java:1721) ~[na:na]
        at java.base/java.util.stream.SortedOps$RefSortingSink.end(SortedOps.java:392) ~[na:na]
        at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258) ~[na:na]
        at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258) ~[na:na]
        at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258) ~[na:na]
        at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258) ~[na:na]
        at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485) ~[na:na]
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) ~[na:na]
        at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913) ~[na:na]
        at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:na]
        at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578) ~[na:na]
        at springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider.requestHandlers(WebMvcRequestHandlerProvider.java:81) ~[springfox-spring-webmvc-3.0.0.jar:3.0.0]
        at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195) ~[na:na]
        at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625) ~[na:na]
        at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484) ~[na:na]
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) ~[na:na]
        at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913) ~[na:na]
        at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:na]
        at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578) ~[na:na]
        at springfox.documentation.spring.web.plugins.AbstractDocumentationPluginsBootstrapper.withDefaults(AbstractDocumentationPluginsBootstrapper.java:107) ~[springfox-spring-web-3.0.0.jar:3.0.0]
        at springfox.documentation.spring.web.plugins.AbstractDocumentationPluginsBootstrapper.buildContext(AbstractDocumentationPluginsBootstrapper.java:91) ~[springfox-spring-web-3.0.0.jar:3.0.0]
        at springfox.documentation.spring.web.plugins.AbstractDocumentationPluginsBootstrapper.bootstrapDocumentationPlugins(AbstractDocumentationPluginsBootstrapper.java:82) ~[springfox-spring-web-3.0.0.jar:3.0.0]
        at springfox.documentation.spring.web.plugins.DocumentationPluginsBootstrapper.start(DocumentationPluginsBootstrapper.java:100) ~[springfox-spring-web-3.0.0.jar:3.0.0]
        at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:178) ~[spring-context-5.3.13.jar:5.3.13]
        ... 14 common frames omitted


FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':bootRun'.
> Process 'command '/home/advance/.sdkman/candidates/java/15.0.2-open/bin/java'' finished with non-zero exit value 1

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.9.1/userguide/command_line_interface.html#sec:command_line_warnings

BUILD FAILED in 2s
5 actionable tasks: 5 executed


【问题讨论】:

只在主类中添加@EnableWebMvc 即可解决问题。 ***.com/a/70703081/5626568 【参考方案1】:

这个问题是由bug in Springfox 引起的。它假设 Spring MVC 的设置方式并不总是成立。具体来说,假设 MVC 的路径匹配将使用基于 Ant 的路径匹配器,而不是基于 PathPattern 的匹配器。基于 PathPattern 的匹配已经有一段时间了,并且是 Spring Boot 2.6 的默认设置。

作为described in Spring Boot 2.6's release notes,您可以通过在application.properties 文件中将spring.mvc.pathmatch.matching-strategy 设置为ant-path-matcher 来恢复Springfox 假定将使用的配置。请注意,这仅在您不使用 Spring Boot 的 Actuator 时才有效。 Actuator 始终使用基于 PathPattern 的解析,与配置的 matching-strategy 无关。如果您想在 Spring Boot 2.6 及更高版本中将其与 Actuator 一起使用,则需要对 Springfox 进行更改。

【讨论】:

感谢您的回答。但是在 application.properties 中添加以下行不起作用。我得到了同样的例外。 spring.mvc.pathmatch.matching-strategy=ant_path_matcher 感谢@Andy,它对我有用 它对我有用! Spring Boot 2.6.0,springfox-boot-starter:3.0.0. 我注意到这个解决方案除了与spring-boot-starter-actuator 不兼容。一旦考虑到这一点,我的所有子模块都可以使用 ant_path_matcher 解决方案。 @g*** 我相信是的,是的。在出现新的 Springfox 版本之前,您要么需要降级到 Spring Boot 2.5,要么从 Springfox 移至 Springdoc 等替代方案。可悲的是,Springfox 似乎不像以前那么活跃了,所以我还是建议考虑替代方案。【参考方案2】:

考虑迁移到springdoc

【讨论】:

谢谢,我迁移到 Springdoc。我等不及 Springfox 团队的解决方案了。 如果您的配置有些复杂,将 springfox 设置迁移到 springdoc 并非易事。【参考方案3】:

不是解决方案,但... 我将 spring-boot-starter-parent 版本从 2.6.0 降级到 2.5.6 并且它开始工作了。

【讨论】:

仍然是一个解决方案 如果是升级修复安全漏洞,是不行的,因为spring boot拉取的依赖库还是会显示漏洞 最好听从安迪或阿纳托利的建议。降级核心框架的版本不是更好的选择。 :) 如果有人走这条路,请使用 2.5.8 或更新版本而不是 2.5.6!【参考方案4】:

以下问题评论中提到的解决方法似乎也适用于使用弹簧执行器的人。仅更改路径匹配器不适用于使用执行器的项目。

https://github.com/springfox/springfox/issues/3462#issuecomment-1010721223

    spring.mvc.pathmatch.matching-strategy 设置为ant_path_matcher in application.properties文件 添加这个 bean:
@Bean
public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebEndpointsSupplier webEndpointsSupplier, ServletEndpointsSupplier servletEndpointsSupplier, ControllerEndpointsSupplier controllerEndpointsSupplier, EndpointMediaTypes endpointMediaTypes, CorsEndpointProperties corsProperties, WebEndpointProperties webEndpointProperties, Environment environment) 
        List<ExposableEndpoint<?>> allEndpoints = new ArrayList();
        Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();
        allEndpoints.addAll(webEndpoints);
        allEndpoints.addAll(servletEndpointsSupplier.getEndpoints());
        allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints());
        String basePath = webEndpointProperties.getBasePath();
        EndpointMapping endpointMapping = new EndpointMapping(basePath);
        boolean shouldRegisterLinksMapping = this.shouldRegisterLinksMapping(webEndpointProperties, environment, basePath);
        return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints, endpointMediaTypes, corsProperties.toCorsConfiguration(), new EndpointLinksResolver(allEndpoints, basePath), shouldRegisterLinksMapping, null);
    


private boolean shouldRegisterLinksMapping(WebEndpointProperties webEndpointProperties, Environment environment, String basePath) 
        return webEndpointProperties.getDiscovery().isEnabled() && (StringUtils.hasText(basePath) || ManagementPortType.get(environment).equals(ManagementPortType.DIFFERENT));
    

【讨论】:

谢谢!如果您不想降级 spring 或者切换到 springdoc 工作量太大,这似乎是最好的答案【参考方案5】:

我将完成 Anatoly 提到的关于使用 sprindoc 的内容。

首先将 springdoc 添加并加载到您的 build.gradle(或 maven)中:

// build.gradle

implementation "org.springdoc:springdoc-openapi-ui:1.6.4"

在你的主类中添加 OpenAPIDefinition 注解:

@SpringBootApplication
@OpenAPIDefinition
public class MyApplication 

    public static void main(String[] args) 
        SpringApplication.run(MyApplication.class, args);
    

现在您可以转到您的 URI/swagger-ui/index.html,它会向您显示 swagger 视图。

【讨论】:

【参考方案6】:

似乎应该迁移到 springdoc-open-api 否则如果您使用引导版本 2.6 或更高版本会出现异常

【讨论】:

【参考方案7】:

删除注释

@EnableSwagger2
@SpringBootApplication
@EnableSwagger2
public class  Applicaiton

【讨论】:

【参考方案8】:

对我来说,它通过添加 @EnableSwagger2 注释来工作

@SpringBootApplication
@EnableSwagger2
public class Application 

【讨论】:

以上是关于Springboot 2.6.0 / Spring fox 3 - 无法启动 bean 'documentationPluginsBootstrapper'的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 2.5.5 发布,2.6.0 也要来了!

@EnableAutoConfiguration(exclude =...) 在 Spring Boot 2.6.0 中的测试失败

Spring Cloud 2021.0.0 正式发布,第一个支持Spring Boot 2.6的版本!

SpringBoot 2.6.0发布:禁止循环依赖,还有哪些实用的更新?

重磅:Spring Boot 2.6 正式发布,一大波新特性,看完我彻底躺平了。。

快报!Spring Boot 2.5.6 发布~我真跟不上了。。。