[springboot] Actuator Dependency And Swagger Stater 3.0.0 Conflict
- Issue
- When I use both Actuator and Swagger in a project, I met below error message
- ERROR org.springframework.boot.SpringApplication: Application run failed org.springframework.context.ApplicationContextException: Failed to start bean ‘documentationPluginsBootstrapper’ - Environment
- Spring boot: 2.7.17
- Spring Actuator: Same version with Spring boot
- Spring fox swagger: 3.0.0
- io.springfox:springfox-swagger2:3.0.0
- io.springfox:springfox-swagger-ui:3.0.0
- io.springfox:springfox-boot-starter:3.0.0
- Reason
- Swagger and Actuator, they two are access endpoint in spring boot. So they have conflict of dependency each other.
- Springfox swagger assume that Spring MVC use to Ant-based path matcher. But Upper Spring MVC 2.6.x is changed from Ant-based path matcher to PathPattern-based matcher.
- Both two make this error
- Solution
- Put below option under application.yml
spring: mvc: pathmatch: matching-strategy: ant_path_matcher
- And then, Regist BeanPostProcessor bean for SpringfoxHandler like below example
@Configuration public class Config { @Bean public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() { return new BeanPostProcessor() { @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) { customizeSpringfoxHandlerMappings(getHandlerMappings(bean)); } return bean; } private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) { List<T> copy = mappings.stream() .filter(mapping -> mapping.getPatternParser() == null) .collect(Collectors.toList()); mappings.clear(); mappings.addAll(copy); } @SuppressWarnings("unchecked") private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) { try { Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings"); field.setAccessible(true); return (List<RequestMappingInfoHandlerMapping>) field.get(bean); } catch (IllegalArgumentException | IllegalAccessException e) { throw new IllegalStateException(e); } } }; }
- Put below option under application.yml
- Reference
- https://dkswnkk.tistory.com/672