헤르메스 LIFE

[ERROR] org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter.report 본문

Exception

[ERROR] org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter.report

헤르메스의날개 2023. 3. 24. 23:44
728x90

요즘 JPA를 공부하고 있습니다. MyBatis 만 하다가, 개인적으로 공부를 진행하고 있습니다. 하다보니 막히고, 이해가 안되는 부분이 많네요. 그때마다 검색과 삽질로 해결하고 있습니다. 여기 그 삽질의 자취를 남겨봅니다.


개발환경

Spring Boot 2.7.9

H2 2.1.214

p6spy 1.8.1

slf4j 1.7.36

swagger2 2.6.1

lombok

devtools

postgresql


INFO  23-03-24 23:26:689[restartedMain] springfox.documentation.spring.web.PropertySourcedRequestMappingHandlerMapping.initHandlerMethods[69]: - Mapped URL path [/v2/api-docs] onto method [springfox.documentation.swagger2.web.Swagger2Controller#getDocumentation(String, HttpServletRequest)]
INFO  23-03-24 23:26:005[restartedMain] springfox.documentation.spring.web.plugins.DocumentationPluginsBootstrapper.start[160]: - Context refreshed
INFO  23-03-24 23:26:021[restartedMain] springfox.documentation.spring.web.plugins.DocumentationPluginsBootstrapper.start[163]: - Found 1 custom documentation plugin(s)
WARN  23-03-24 23:26:024[restartedMain] org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext.refresh[591]: - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NoSuchMethodError: 'org.springframework.plugin.core.Plugin org.springframework.plugin.core.PluginRegistry.getPluginFor(java.lang.Object, org.springframework.plugin.core.Plugin)'
INFO  23-03-24 23:26:031[restartedMain] com.zaxxer.hikari.HikariDataSource.close[350]: - HikariPool-1 - Shutdown initiated...
INFO  23-03-24 23:26:043[restartedMain] com.zaxxer.hikari.HikariDataSource.close[352]: - HikariPool-1 - Shutdown completed.
INFO  23-03-24 23:26:253[restartedMain] org.apache.catalina.core.StandardService.log[173]: - Stopping service [Tomcat]
ERROR 23-03-24 23:26:278[restartedMain] org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter.report[40]: - 

***************************
APPLICATION FAILED TO START
***************************

Description:

An attempt was made to call a method that does not exist. The attempt was made from the following location:

    springfox.documentation.spring.web.plugins.DocumentationPluginsManager.createContextBuilder(DocumentationPluginsManager.java:152)

The following method did not exist:

    'org.springframework.plugin.core.Plugin org.springframework.plugin.core.PluginRegistry.getPluginFor(java.lang.Object, org.springframework.plugin.core.Plugin)'

The calling method's class, springfox.documentation.spring.web.plugins.DocumentationPluginsManager, was loaded from the following location:

    jar:file:/C:/Users/jongyoung.park/.gradle/caches/modules-2/files-2.1/io.springfox/springfox-spring-web/2.9.2/ed2ed714a6cba8804d00f80f0534901e4c7a3211/springfox-spring-web-2.9.2.jar!/springfox/documentation/spring/web/plugins/DocumentationPluginsManager.class

The called method's class, org.springframework.plugin.core.PluginRegistry, is available from the following locations:

    jar:file:/C:/Users/jongyoung.park/.gradle/caches/modules-2/files-2.1/org.springframework.plugin/spring-plugin-core/2.0.0.RELEASE/95fc8c13037630f4aba9c51141f535becec00fe6/spring-plugin-core-2.0.0.RELEASE.jar!/org/springframework/plugin/core/PluginRegistry.class

The called method's class hierarchy was loaded from the following locations:

    org.springframework.plugin.core.PluginRegistry: file:/C:/Users/jongyoung.park/.gradle/caches/modules-2/files-2.1/org.springframework.plugin/spring-plugin-core/2.0.0.RELEASE/95fc8c13037630f4aba9c51141f535becec00fe6/spring-plugin-core-2.0.0.RELEASE.jar


Action:

Correct the classpath of your application so that it contains compatible versions of the classes springfox.documentation.spring.web.plugins.DocumentationPluginsManager and org.springframework.plugin.core.PluginRegistry

원인은 HATEOAS와 Swagger와 같이 사용하면서 충돌이 발생한 오류 입니다.
Swagger는 2.9.2 버전을 사용하고 있고,
spring-plugin-core는 2.0.0.RELEASE 버전을 사용하게 되면서 충돌이 발생해서 발생되는 오류로 보여집니다.
이 경우 spring-plugin-core 의 버전을 1.2.0.RELEASE 버전으로 강제로 낮춰줘야 합니다.


build.gradle

    // Default : 2.0.0.RELEASE
    //implementation 'org.springframework.plugin:spring-plugin-core'
    implementation 'org.springframework.plugin:spring-plugin-core:1.2.0.RELEASE'
    // HATEOAS 라이브러리 추가 Default : 1.5.3
    implementation 'org.springframework.boot:spring-boot-starter-hateoas'
    // Swagger	
    implementation 'io.springfox:springfox-swagger2:2.9.2'
    implementation 'io.springfox:springfox-swagger-ui:2.9.2'

추가로 아래의 내용을 추가합니다.

SwaggerConfiguration.java

@Bean
public LinkDiscoverers discoverers() {
    List<LinkDiscoverer> plugins = new ArrayList<>();
    plugins.add(new CollectionJsonLinkDiscoverer());
    return new LinkDiscoverers(SimplePluginRegistry.create(plugins));
}

추가적으로 또 다른 방법은..

Swagger를 3.0.0 으로 업그레이드 시키면 됩니다.

참고로

Swagger 의 버전별 call URL이 다릅니다.

2.x 버전 : http://localhost:9090/swagger-ui.html

3.x 버전 : http://localhost:9090/swagger-ui/index.html

build.gradle

// Swagger
// springfox-swagger2:2.x.x => http://localhost:9090/swagger-ui.html
//implementation 'io.springfox:springfox-swagger2:2.9.2'
//implementation 'io.springfox:springfox-swagger-ui:2.9.2'
// springfox-swagger2:3.x.x => http://localhost:9090/swagger-ui/index.html
implementation 'io.springfox:springfox-boot-starter:3.0.0'
implementation 'io.springfox:springfox-swagger-ui:3.0.0'

SwaggerConfiguration.java

package octopus.config;                                                                                                                                                                                        
                                                                                                                                                                                                               
import org.springframework.context.annotation.Bean;                                                                                                                                                            
import org.springframework.context.annotation.Configuration;                                                                                                                                                   
                                                                                                                                                                                                               
import springfox.documentation.builders.ApiInfoBuilder;                                                                                                                                                        
import springfox.documentation.builders.PathSelectors;                                                                                                                                                         
import springfox.documentation.builders.RequestHandlerSelectors;                                                                                                                                               
import springfox.documentation.service.ApiInfo;                                                                                                                                                                
import springfox.documentation.spi.DocumentationType;                                                                                                                                                          
import springfox.documentation.spring.web.plugins.Docket;                                                                                                                                                      
import springfox.documentation.swagger2.annotations.EnableSwagger2;                                                                                                                                            
                                                                                                                                                                                                               
@Configuration                                                                                                                                                                                                 
@EnableSwagger2                                                                                                                                                                                                
public class SwaggerConfiguration {                                                                                                                                                                            
    @Bean                                                                                                                                                                                                      
    public Docket swaggerApi() {                                                                                                                                                                               
        return new Docket(DocumentationType.SWAGGER_2).apiInfo(swaggerInfo()).select()                                                                                                                         
                .apis(RequestHandlerSelectors.basePackage("octopus.backend")).paths(PathSelectors.any()).build()                                                                                               
                .useDefaultResponseMessages(false); // 기본으로 세팅되는 200,401,403,404 메시지를 표시 하지 않음                                                                                                                 
    }                                                                                                                                                                                                          
                                                                                                                                                                                                               
    private ApiInfo swaggerInfo() {                                                                                                                                                                            
        return new ApiInfoBuilder().title("Octopus API Documentation").description("앱 개발시 사용되는 서버 API에 대한 연동 문서입니다")                                                                                           
                .license("MIT License").licenseUrl("https://hermeslog.tistory.com/").version("1.0").build();                                                                                                   
    }                                                                                                                                                                                                          
                                                                                                                                                                                                               
    // @Bean                                                                                                                                                                                                   
    // public LinkDiscoverers discoverers() {                                                                                                                                                                  
    // List<LinkDiscoverer> plugins = new ArrayList<>();                                                                                                                                                       
    // plugins.add(new CollectionJsonLinkDiscoverer());                                                                                                                                                        
    //                                                                                                                                                                                                         
    // return new LinkDiscoverers(SimplePluginRegistry.create(plugins));                                                                                                                                       
    // }                                                                                                                                                                                                       
}
728x90