Spring Boot2.6에서 Springfox3 실행 실패 에러

작성: 2022.05.08

수정: 2022.05.08

읽는시간: 00 분

Development/Daily Error

반응형

Intro

Kotlin 프로젝트 였지만, Spring Boot 설정과 관련된 내용이기 때문에 java 로 프로젝트를 진행 하시는 경우에도 문제 해결을 하실 수 있습니다.

Kotlin 과 스프링 부트를 이용해 API 서버를 만드는 강의를 따라 실습 해 보던 중 에러가 발생했습니다.

강의에서는 springfox 2.x 버전을 사용하며 새로나온 3.x 버전은 설정과정이 살짝 다르기때문에 구버전을 사용한다고는 했지만, 저는 얼마전 회사에서 진행중인 프로젝트에 springfox3.0.0 버전을 이용해 적용을 시켜본 경험이 있기 때문에 별 고민없이 3.0.0 버전을 적용 시켰습니다.

build.gradle.kts

implementation("io.springfox:springfox-swagger-ui:2.9.2")
implementation("io.springfox:springfox-swagger2:3.0.0")

SwaggerConfig.kt

@Configuration
@EnableSwagger2
class SwaggerConfig {
    @Bean
    fun docket(): Docket {
        return Docket(DocumentationType.SWAGGER_2)
            .select()
            .apis(RequestHandlerSelectors.any())
            .paths(PathSelectors.any())
            .build()
    }

}

에러

간단한 Swagger 설정을 한 뒤에, 프로젝트를 실행 하려고 하는데 실행이 되지 않고 에러가 발생했습니다.

image-20220508220242753

이 중에 핵심 에러 메시지는 아래 두 줄 같은데

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
Caused by: java.lang.NullPointerException: Cannot invoke "org.springframework.web.servlet.mvc.condition.PatternsRequestCondition.getPatterns()" because "this.condition" is null

읽어보면, mvc 설정을 하던 중에 this.condition 부분에 NullPointerException을 발생 시키고 있습니다.

원인

관련된 에러를 트래킹 해 보니

Springfox의 에러라고 합니다. 이미 일년이 넘도록 알려진 이슈지만 해결 되지 못하고 있다고 하는데요.. 2021년 초에 https://github.com/spring-projects/spring-boot/issues/24645 이슈를 처리하는 과정에서 스프링 부트 2.6.0 버전부터 적용된 변경 사항이 springfox 의 기존 작동에 문제를 일으켰다고 합니다.

image-20220508221024091

Springfox 프로젝트가 더이상 유지보수가 되지 않고 있지만 여전히 인기있는 라이브러리다 보니 스프링팀에서도 이러지도 못하는 참 곤란한 상황이라고 하네요.

대부분은 유지보수 되지 않고 버그가 많은 springfox 대신 springdoc 사용을 고려해 보라고 권장 합니다.

해결

이것 저것 설정을 바꿔보다 보니 몇가지 해결 방법이 있었습니다.

첫번째로는 @EnableSwagger2 어노테이션을 제거 하는 방법입니다.

생각해보니 회사에서 적용할때는 제가 따로 설정파일을 작성하지 않고, 메인클래스에 Docket만 Bean으로 등록 해 줬었는데, 혹시 @EnableSwagger2 어노테이션이 문제인가 싶어 제거 해 보았습니다.

@Configuration
class SwaggerConfig {
    @Bean
    fun docket(): Docket {
        return Docket(DocumentationType.SWAGGER_2)
            .select()
            .apis(RequestHandlerSelectors.any())
            .paths(PathSelectors.any())
            .build()
    }

}

변경 이후 실행 해 보니

image-20220508222144782

일단 어플리케이션이 문제 없이 실행 됩니다.

이제 API 를 잘 문서화 해 주었는지 확인 해 봅니다.

http://localhost:8080/swagger-ui.html

image-20220508222740433

일단 뜨긴 하는데, base url을 찾지를 못한다는 에러가 나옵니다.

Unable to infer base url. This is common when using dynamic servlet registration or when the API is behind an API Gateway. The base url is the root of where all the swagger resources are served. For e.g. if the api is available at http://example.org/api/v2/api-docs then the base url is http://example.org/api/. Please enter the location manually: 

이번이슈는 보통 security 이슈라는데요. 저는 이 프로젝트에 SpringSecurity를 따로 적용하지 않았음에도 이런 문제가 발생 했습니다.

혹시 스프링 시큐리티 뒤에 API가 숨어 있어서 이 문제가 발생하는 분들은

.antMatchers("/swagger-resources/**").permitAll()

를 해 보시고.. 저는 여기에서 의존성을 예전에 해봐서 익숙한 걸로 변경을 했습니다.

변경 전

implementation("io.springfox:springfox-swagger-ui:2.9.2")
implementation("io.springfox:springfox-swagger2:3.0.0")

변경 후

implementation("io.springfox:springfox-boot-starter:3.0.0")
implementation("io.springfox:springfox-swagger-ui:3.0.0")

그러고 시작을 하니, 또

Caused by: java.lang.NullPointerException: Cannot invoke "org.springframework.web.servlet.mvc.condition.PatternsRequestCondition.getPatterns()" because "this.condition" is null

에러가 발생하는데요. 이번에는 @EnableSwagger2 어노테이션이 없는데도 발생했습니다.

이번에는 @EnableWebMvc 어노테이션을 붙여 해결해 주었습니다.

@Configuration
@EnableWebMvc
class SwaggerConfig {
    @Bean
    fun docket(): Docket {
        return Docket(DocumentationType.SWAGGER_2)
            .select()
            .apis(RequestHandlerSelectors.any())
            .paths(PathSelectors.any())
            .build()
    }
}

image-20220508230211259

이제 정상적으로 실행이 됩니다.

springfox-boot-starter로 의존성을 변경 하며, API document 접근 주소도 변경 되었습니다.

http://localhost:8080/swagger-ui/index.html

이제 해당 링크를 확인 해 보면

image-20220508230419747

기나긴 고생 끝에 Swagger 페이지를 띄우는데 성공 했습니다.

이상입니다.

반응형