programing

"org.springframework"를 호출할 수 없습니다.web.servlet.mvc.condition."this.condition"이(가) null이기 때문에 PatternsRequestCondition.getPatterns()"입니다.

magicmemo 2023. 7. 10. 22:15
반응형

"org.springframework"를 호출할 수 없습니다.web.servlet.mvc.condition."this.condition"이(가) null이기 때문에 PatternsRequestCondition.getPatterns()"입니다.

SpringBoot 2.6.7로 Springdoc을 실행하려고 합니다.

구성:

@Configuration
public class SwaggerConfiguration {
  
  @Bean
  public GroupedOpenApi publicApi() {
    return GroupedOpenApi.builder()
            .group("springshop-public")
            .pathsToMatch("/public/**")
            .build();
  }
}

오류 스택:

00:50:54.956 [main] ERROR SpringApplication[reportFailure:830] - 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)
    at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:54)
    at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:356)
    at java.base/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:740)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:415)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1312)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301)
    at com.atlas.psp.AtlasRouterApplication.main(AtlasRouterApplication.java:53)
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)
    at springfox.documentation.RequestHandler.sortedPaths(RequestHandler.java:113)
    at springfox.documentation.spi.service.contexts.Orderings.lambda$byPatternsCondition$3(Orderings.java:89)
    at java.base/java.util.Comparator.lambda$comparing$77a9974f$1(Comparator.java:473)
    at java.base/java.util.TimSort.countRunAndMakeAscending(TimSort.java:355)
    at java.base/java.util.TimSort.sort(TimSort.java:234)
    at java.base/java.util.Arrays.sort(Arrays.java:1307)
    at java.base/java.util.ArrayList.sort(ArrayList.java:1721)
    at java.base/java.util.stream.SortedOps$RefSortingSink.end(SortedOps.java:392)
    at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258)
    at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258)
    at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258)
    at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:510)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
    at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
    at springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider.requestHandlers(WebMvcRequestHandlerProvider.java:81)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
    at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
    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.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
    at springfox.documentation.spring.web.plugins.AbstractDocumentationPluginsBootstrapper.withDefaults(AbstractDocumentationPluginsBootstrapper.java:107)
    at springfox.documentation.spring.web.plugins.AbstractDocumentationPluginsBootstrapper.buildContext(AbstractDocumentationPluginsBootstrapper.java:91)
    at springfox.documentation.spring.web.plugins.AbstractDocumentationPluginsBootstrapper.bootstrapDocumentationPlugins(AbstractDocumentationPluginsBootstrapper.java:82)
    at springfox.documentation.spring.web.plugins.DocumentationPluginsBootstrapper.start(DocumentationPluginsBootstrapper.java:100)
    at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:178)
    ... 14 common frames omitted

이 문제를 해결할 방법이 있습니까?

이 문제는 Spring Boot 2.6에 도입된 새로운 PathPatternParser로 인해 발생합니다.두 가지 방법으로 해결할 수 있습니다.

댓글에 @gsan이 제안한 것처럼, 다음을 추가합니다.application.yml또는application.properties:

spring.mvc.pathmatch.matching-strategy=ant_path_matcher

OR

구성 클래스에 다음 빈을 추가합니다.

@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 Boot 2.6 + Swagger 시작 예외: "this.condition"이 null이기 때문입니다.

흠, @Lyncean Patel이 언급한 답은 100% 정확하지 않습니다. 왜냐하면 이것을 고치는 데 OR이 없기 때문입니다.Github 이슈 토론 스레드에서 두 가지를 모두 수행하기 위해 수정하는 방법:

  1. 세트spring.mvc.pathmatch.matching-strategy: ant_path_matcherapplication.properties에서
  2. 이 콩을 첨가하세요.
@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));
    }

저도 같은 문제가 있었고, 이 문제는 다음에 구성을 추가하는 방식으로 작동했습니다.application.yml그리고 내 안에서 콩을 만드는 것.SwaggerConfig학급.

  • 스프링 부트 2.7.3
  • 자바 17
  • springfox-boot-boot-tunnel 3.0.0

springdoc-openapi-ui 1.6.11을 사용할 때는 다음 항목만 추가하면 됩니다.application.yml@Lyncean Patel이 제안한 대로 구성합니다.

풀었어요.스프링부츠 2.6.12와 스웨거 3.0을 사용했습니다.다음은 메이븐 구성입니다.

 <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
        <version>3.0.0</version>
    </dependency>
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <version>3.0.0</version>
    </dependency>

그런 다음 WebMvcRequestHandlerProvider.java를 재정의해야 합니다(생성자를 복사하고 재정의하여 비정상적인 생성자를 필터링합니다).

 this.handlerMappings = handlerMappings.stream().filter(mapping -> mapping.getPatternParser() == null)
            .collect(Collectors.toList());

다른 모든 것은 그대로 유지됨 클래스:springfox.documentation.spring.web.plugins와 동일한 이름을 가진 새 패키지를 프로젝트 홈 디렉토리에 생성해야 합니다.

행운을 빕니다!

springdoc으로의 마이그레이션을 고려

마이그레이션은 매우 원활한 프로세스이며 이러한 버그가 발생할 가능성은 거의 없습니다.

저는 스프링폭스 의존성을 모두 제거하고 추가함으로써 이 모든 문제를 해결했습니다.implementation 'org.springdoc:springdoc-openapi-ui:1.6.12'나에게build.gradle파일(maven을 사용하여 해당 요소를 추가하는 경우) 그러면 내 SecurityFilterChain 빈은 다음과 같이 보입니다.

...
@Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.cors().and()
                .authorizeRequests().antMatchers("/actuator/**").permitAll()
                .and().authorizeRequests().antMatchers("/swagger-ui/**").permitAll()
                .and().authorizeRequests().antMatchers("/v3/api-docs/**").permitAll();
        return http.build();
}
...

추가 종속성 또는 구성이 필요하지 않습니다.

나는 kts 파일에서 이 종속성을 -> 구현("org.apache.commons:commons-lang3:3.12.0")을 사용했고 나는 이 종속성을 제거한 후 이 오류를 사용하지 않습니다. 종속성 : Apache Tomcat

아래 속성을 추가하는 것도 저에게 효과가 있었습니다.

spring.mvc.pathmatch.matching-strategy: ant_path_matcher

하지만 스프링 작동기 의존성이 있는 다른 프로젝트에서는 작동하지 않았습니다. 왜 작동하지 않는지 궁금하다면 작동기의 존재 때문일 수도 있습니다.그래서, 저는 허세를 버려야만 했습니다.

언급URL : https://stackoverflow.com/questions/72235752/cannot-invoke-org-springframework-web-servlet-mvc-condition-patternsrequestcond

반응형