pring-boot-starter-actuator是spring提供的监控模块。在运行中,需实时和定时监控服务各项状态和可用性。提供很多监控接口,可对应用系统进行配置查看、相关统计等。
Swagger 是一个规范和完整的框架,生成、描述、调用和可视化 RESTful 风格的 Web 服务。是OpenAPI规范Java实现。
问题是,项目开始只引用了 swagger 启动没问题,在最近需要监控项目的时候,引入了actuator和prometheus,启动报错:Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException
参考
使用本链接内容解决:SpringBoot2.6,在有spring-boot-starter-actuator依赖的情况下报错,2.5.7正常启动
spring-boot-start-actuator版本2.6.x之后导致swagger冲突问题
SpringBoot2.6.x集成swagger: Failed to start bean ‘documentationPluginsBootstrapper问题解决
SpringBoot教程(十六) | SpringBoot集成swagger(全网最全)
springboot整合swagger2依赖冲突问题解决思路
knife4j和springboot-actuator版本冲突问题
knife4j介绍
记录
pom
大概内容如下
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.6.3</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<swagger2.version>2.9.2</swagger2.version>
...
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
...
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger2.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger2.version}</version>
</dependency>
...
<!-- 以上内容启动没问题,增加下面内容启动失败 -->
<!-- 增加springboot的指标检测 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- 增加springboot的prometheus监控指标检测 -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<dependencies>
报错日志
org.springframework.context.ApplicationContextException: Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:181)
at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:54)
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:356)
at java.lang.Iterable.forEach(Iterable.java:75)
at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:155)
at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:123)
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:935)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:586)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:414)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:302)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292)
at org.xxx.xxx.XXXApplication.main(XXXApplication.java:36)
Caused by: java.lang.NullPointerException: null
at springfox.documentation.spi.service.contexts.Orderings$8.compare(Orderings.java:112)
at springfox.documentation.spi.service.contexts.Orderings$8.compare(Orderings.java:109)
at com.google.common.collect.ComparatorOrdering.compare(ComparatorOrdering.java:37)
at java.util.TimSort.countRunAndMakeAscending(TimSort.java:355)
at java.util.TimSort.sort(TimSort.java:234)
at java.util.Arrays.sort(Arrays.java:1438)
at com.google.common.collect.Ordering.sortedCopy(Ordering.java:852)
at springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider.requestHandlers(WebMvcRequestHandlerProvider.java:57)
at springfox.documentation.spring.web.plugins.DocumentationPluginsBootstrapper$2.apply(DocumentationPluginsBootstrapper.java:138)
at springfox.documentation.spring.web.plugins.DocumentationPluginsBootstrapper$2.apply(DocumentationPluginsBootstrapper.java:135)
at com.google.common.collect.Iterators$6.transform(Iterators.java:788)
at com.google.common.collect.TransformedIterator.next(TransformedIterator.java:47)
at com.google.common.collect.TransformedIterator.next(TransformedIterator.java:47)
at com.google.common.collect.Iterators$ConcatenatedIterator.hasNext(Iterators.java:1340)
at com.google.common.collect.ImmutableList.copyOf(ImmutableList.java:270)
at com.google.common.collect.ImmutableList.copyOf(ImmutableList.java:234)
at com.google.common.collect.FluentIterable.toList(FluentIterable.java:617)
at springfox.documentation.spring.web.plugins.DocumentationPluginsBootstrapper.defaultContextBuilder(DocumentationPluginsBootstrapper.java:111)
at springfox.documentation.spring.web.plugins.DocumentationPluginsBootstrapper.buildContext(DocumentationPluginsBootstrapper.java:96)
at springfox.documentation.spring.web.plugins.DocumentationPluginsBootstrapper.start(DocumentationPluginsBootstrapper.java:167)
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:178)
... 14 common frames omitted
解决思路
明显是版本冲突导致的,随便搜一下就可以找到问题的大致说明:
因Springfox 使用的路径匹配是基于AntPathMatcher的,而Spring Boot 2.6.X使用的是PathPatternMatcher。
解决方式1-降低springboot版本-未采用
考虑到项目已上线,故不太建议轻易变动框架版本
解决方式2-actuator增加解决代码
增加配置
spring:
mvc:
pathmatch:
matching-strategy: ant_path_matcher
增加处理代码
import org.springframework.boot.actuate.autoconfigure.endpoint.web.CorsEndpointProperties;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType;
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
import org.springframework.boot.actuate.endpoint.web.*;
import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointsSupplier;
import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier;
import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* 解决依赖代码冲突问题
*
* @author z.y.
* @version v1.0
* @date 2022
*/
@Configuration
public class ConflictHandlingCfg {
/**
* 解决springboot升到2.6.x之后,knife4j报错
* 原文链接:https://gitee.com/xiaoym/knife4j/issues/I4JT89
* @param wes the web endpoints supplier
* @param ses the servlet endpoints supplier
* @param ces the controller endpoints supplier
* @param emt the endpoint media types
* @param cep the cors properties
* @param wep the web endpoints properties
* @param env the environment
* @return the web mvc endpoint handler mapping
*/
@Bean
public WebMvcEndpointHandlerMapping webMvcEndpointHandlerMapping(WebEndpointsSupplier wes
, ServletEndpointsSupplier ses, ControllerEndpointsSupplier ces, EndpointMediaTypes emt
, CorsEndpointProperties cep, WebEndpointProperties wep,Environment env) {
List<ExposableEndpoint<?>> allEndpoints = new ArrayList<>();
Collection<ExposableWebEndpoint> webEndpoints = wes.getEndpoints();
allEndpoints.addAll(webEndpoints);
allEndpoints.addAll(ses.getEndpoints());
allEndpoints.addAll(ces.getEndpoints());
String basePath = wep.getBasePath();
EndpointMapping endpointMapping = new EndpointMapping(basePath);
boolean shouldRegisterLinksMapping = shouldRegisterLinksMapping(wep, env, basePath);
return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints, emt
, cep.toCorsConfiguration(), new EndpointLinksResolver(
allEndpoints, basePath), shouldRegisterLinksMapping, null);
}
/**
* shouldRegisterLinksMapping
*
* @param wep
* @param env
* @param basePath
* @return
*/
private boolean shouldRegisterLinksMapping(WebEndpointProperties wep, Environment env, String basePath) {
return wep.getDiscovery().isEnabled() && (StringUtils.hasText(basePath) || ManagementPortType.get(env).equals(ManagementPortType.DIFFERENT));
}
}
问题解决。记录一下