2

I saw this issue: Springboot 2.6.0 / Spring fox 3 - Failed to start bean 'documentationPluginsBootstrapper' Top answer say to put configuration property like that spring.mvc.pathmatch.matching-strategy: ant-path-matcher And it's working perfectly, but not if you have Actuator dependency.

Is there a way to 'befriend' Spring Boot 2.6.x with Actuator with SpringFox 3.0.0?

Stacktrace:

2022-01-13 09:49:15.745 ERROR 31452 --- [           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 de.hdl.formstacksalesobjectinserter.FormstackSalesObjectInserterApplication.main(FormstackSalesObjectInserterApplication.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:473) ~[na:na]
    at java.base/java.util.TimSort.countRunAndMakeAscending(TimSort.java:355) ~[na:na]
    at java.base/java.util.TimSort.sort(TimSort.java:234) ~[na:na]
    at java.base/java.util.Arrays.sort(Arrays.java:1307) ~[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]
Artique
  • 86
  • 2
  • 6
  • Consider moving to `springdoc` instead. Check some reasons why in https://stackoverflow.com/questions/70178343/springfox-3-0-0-is-not-working-with-spring-boot-2-6-0/70178391#70178391. – João Dias Jan 13 '22 at 17:08
  • @JoãoDias I've heard of springdoc. Is it like a better version of SpringFox? SpringFox seem to be badly supported nowadays. But Idk, is it worth migrating all microservices to it? What's your experience on that? – Artique Jan 19 '22 at 08:59
  • 1
    Yes, please do. SpringFox is a very slow-moving project nowadays. springdoc is exactly the opposite. Its maintainers answer very quickly any issue that is raised in https://github.com/springdoc/springdoc-openapi/issues (as you can see there is only one open issue versus 274 in SpringFox). Of course SpringFox had its merits back then when it was created but today there are better alternatives. As you can read in the link I provided before, we moved to springdoc more than 2 years ago and so far so good. I really recommend it. – João Dias Jan 19 '22 at 10:49

2 Answers2

1

I have same question, and get answers from springfox issue. Here's github issue!

Maybe you can try the following two ways first, which I saw from this issue and solved my problem.

  1. you can try add spring.mvc.pathmatch.matching-strategy=ant-path-matcher in your application.properties, or application.yml.
  2. add this bean to your app, note the need to add @Configuration on your config class
@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);
            }
        }
    };
}
robert s
  • 11
  • 1
  • yes, this works, but only if you don't have Actuator. But I need actuator in my projects. – Artique Jan 19 '22 at 09:21
  • I use Springboot-2.6.1 , spring-boot-starter-actuator-2.6.1 , springfox-boot-starter-3.0.0 in my project. When I use the second solution, my project can start normally. Of course, both methods can be configured at the same time. You can check the [official documentation](http://springfox.github.io/springfox/docs/current/#maven), maven dependencies have been integrated since swagger 3.0. – robert s Jan 20 '22 at 15:27
  • 1
    Thanks, I've anded up migrating to springdoc ;) – Artique Dec 11 '22 at 16:54
0

It's true that actuator doesn't work with springfox 2022 spring boot 3.0.1 and springfox 3.0.0, springfox is using ant_path_matcher which you should configure in the properties file as: spring.mvc.pathmatch.matching-strategy=ant-path-matcher. Otherwise when you have actuator in place, try adding the stated bean above, it worked for me. Thanks. Happy coding friends!

  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Kunal Varpe Jan 04 '23 at 07:22
  • Hello Kevin. Your answer, while helpful, is the same as the other currently unaccepted answer without providing any further clarifying details or alternate strategies. When providing answers, please try refrain from restating answers from other users. I suggest checking out the [How do I write a good answer](https://stackoverflow.com/help/how-to-answer) page for more details. – tbatch Jan 04 '23 at 20:08