LANGUAGE/!$%!% ERROR NOTE 2021. 1. 5. 20:24

SpringBoot 1.5.4 + ElasticSearch 7.3.2

SpringBoot에 물려서 높은 버전의 ElasticSearch로 설정할 경우 오류가 발생하는 경우가 있지만 해결방법은 있다.

1. Error

  • Error

      Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'elasticSearchConfig': Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: org/elasticsearch/common/CheckedConsumer
      ...
      Caused by: java.lang.NoClassDefFoundError: org/elasticsearch/common/CheckedConsumer
      ...
      Caused by: java.lang.ClassNotFoundException: org.elasticsearch.common.CheckedConsumer
          at java.net.URLClassLoader.findClass(URLClassLoader.java:382) ~[na:1.8.0_211]
          at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_211]
          at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349) ~[na:1.8.0_211]
          at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_211]
          ... 87 common frames omitted

2. Problem

SpringBoot에서 제공해주는 ElasticSearch API에서 벗어나서 더 높은 버전의 독립된 API로 업그레이드 하는 상황에서 발생하였다.

  • ※ 환경
    • JDK: 1.8
    • Gradle: 4.10.3
    • SpringBoot: 1.5.4
    • ElasticSearch: 7.3.2

BEFORE

  • build.gradle

      compile 'org.elasticsearch:elasticsearch:1.5.2'
      compile 'org.springframework.data:spring-data-commons:1.11.4.RELEASE'
      compile 'org.springframework.data:spring-data-elasticsearch:1.3.4.RELEASE'

AFTER

  • build.gradle

     compile "org.elasticsearch:elasticsearch:7.3.2"
     compile "org.elasticsearch.client:elasticsearch-rest-client:7.3.2"
     compile "org.elasticsearch.client:elasticsearch-rest-high-level-client:7.3.2"

7.3.2로 변경하는 과정에서 어떻게하더라도 2.4.5버전의 elasticsearch에 의존성이 설정되어 오류가 발생하는 것으로 보인다.
gradle로 의존성을 tree구조로 확인해보면 명시한 버전(7.3.2)이 아닌 자동으로 옛버전(2.4.5)으로 강제설정되는 것을 알 수 있다.

  • Command Line에서 Gradle을 사용하여 tree구조로 의존성 보기

      gradle dependencies
      +--- org.elasticsearch:elasticsearch:7.3.2 -> 2.4.5

'spring-boot' plugin이 SpringBoot버전에 가장 적합한 ElasticSearch로 전환시켜버리는 모양이다.

3. Solved

시도 1. (실패)

내가 아는 의존성모듈의 버전 강제하는 방법을 시도하였으나 적용되지 않았다.

  • build.gradle

      configurations.all {
          resolutionStrategy.eachDependency { DependencyResolveDetails details ->
              def req = details.requested
              if (req.group == 'org.elasticsearch' && req.name == 'elasticsearch'){            
                  details.useVersion '7.3.2'
                  details.because "$req.group:$req.name:$req.version ==> Correct to official IRUDA Session Version ==> 7.3.2"
              }
    
          }
      }

시도 2. (성공)

'spring-boot' plugin이 의존성을 특정할 수 있도록 ext 변수를 적용하여 설정하는 옵션을 제공한다.

  • build.gradle

      ext {
          set('elasticsearch.version', elasticsearch_version)
      }

시도 3. (성공)

또는 'spring-boot' plugin의 dependencyManagement 기능을 이용하여 특정할 수 있다.

  • build.gradle

      dependencyManagement {
          dependencies {
              dependency group:'org.elasticsearch', name:'elasticsearch', version:'7.3.2'
          }
      }

4. Reference