3
头图

概述

最近由于一些原因需要升级 spring boot 版本,项目原来的版本是 spring boot 2.1.2.RELEASE,现在把版本升级到 spring boot 2.4.1,项目一启动就报如下错误,通过查阅官方文档,一步一步解决了这个问题,在这里记录一下,希望对遇到同样问题的小伙伴提供一些帮助。

说明:我使用的 elasticsearch 的版本是 6.7.0

升级spring boot 版本后报错如下

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'elasticsearchTemplate' defined in class path resource [org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchDataConfiguration$RestClientConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate]: Factory method 'elasticsearchTemplate' threw exception; nested exception is java.lang.BootstrapMethodError: java.lang.NoClassDefFoundError: org/elasticsearch/client/core/MainResponse
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:658) ~[spring-beans-5.3.2.jar:5.3.2]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:638) ~[spring-beans-5.3.2.jar:5.3.2]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1336) ~[spring-beans-5.3.2.jar:5.3.2]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1179) ~[spring-beans-5.3.2.jar:5.3.2]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:571) ~[spring-beans-5.3.2.jar:5.3.2]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:531) ~[spring-beans-5.3.2.jar:5.3.2]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.2.jar:5.3.2]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.2.jar:5.3.2]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.2.jar:5.3.2]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.2.jar:5.3.2]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944) ~[spring-beans-5.3.2.jar:5.3.2]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:923) ~[spring-context-5.3.2.jar:5.3.2]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:588) ~[spring-context-5.3.2.jar:5.3.2]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:144) ~[spring-boot-2.4.1.jar:2.4.1]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:767) [spring-boot-2.4.1.jar:2.4.1]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) [spring-boot-2.4.1.jar:2.4.1]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:426) [spring-boot-2.4.1.jar:2.4.1]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:326) [spring-boot-2.4.1.jar:2.4.1]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1309) [spring-boot-2.4.1.jar:2.4.1]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1298) [spring-boot-2.4.1.jar:2.4.1]
    at com.southcn.nfplus.NfplusEsSearchApplication.main(NfplusEsSearchApplication.java:10) [classes/:na]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate]: Factory method 'elasticsearchTemplate' threw exception; nested exception is java.lang.BootstrapMethodError: java.lang.NoClassDefFoundError: org/elasticsearch/client/core/MainResponse
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.3.2.jar:5.3.2]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653) ~[spring-beans-5.3.2.jar:5.3.2]
    ... 20 common frames omitted
Caused by: java.lang.BootstrapMethodError: java.lang.NoClassDefFoundError: org/elasticsearch/client/core/MainResponse
    at org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate.getClusterVersion(ElasticsearchRestTemplate.java:373) ~[spring-data-elasticsearch-4.1.2.jar:4.1.2]
    at org.springframework.data.elasticsearch.core.AbstractElasticsearchTemplate.initialize(AbstractElasticsearchTemplate.java:95) ~[spring-data-elasticsearch-4.1.2.jar:4.1.2]
    at org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate.<init>(ElasticsearchRestTemplate.java:116) ~[spring-data-elasticsearch-4.1.2.jar:4.1.2]
    at org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataConfiguration$RestClientConfiguration.elasticsearchTemplate(ElasticsearchDataConfiguration.java:74) ~[spring-boot-autoconfigure-2.4.1.jar:2.4.1]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_131]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_131]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_131]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_131]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.3.2.jar:5.3.2]
    ... 21 common frames omitted
Caused by: java.lang.NoClassDefFoundError: org/elasticsearch/client/core/MainResponse
    ... 30 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.elasticsearch.client.core.MainResponse
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_131]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_131]
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335) ~[na:1.8.0_131]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_131]
    ... 30 common frames omitted

原因分析

查看spring data elasticsearch 官网:Spring Data Elasticsearch 4.2.0 官方文档

有如下版本说明:
image.png

我们还可以查看 spring-boot-dependencies: 2.4.1spring-boot-dependencies: 2.1.2.RELEASE 的 pom.xml 文件,搜索 elasticersearch 的版本,可以看到如下图所示的默认版本号:

image.png
image.png

从上面的分析我们可以知道,默认情况下:
spring boot 2.1.2.RELEASE 对应的 elasticsearch 版本是 6.4.3, 对应的 spring data elsaticsearch 3.1.x;
spring boot 2.4.1 对应的 elasticsearch 版本是 7.9.3, 对应的 spring data elsaticsearch 4.1.x;
所以我们可以知道,由于版本不兼容导致上面的报错,一个主要的原因是 elasticsearch 6.x 和 elasticsearch 7.x 存在版本不兼容的问题。

解决方法

从上面的分析我们已经知道是版本不兼容导致的问题,所以我们只需要手动修改为我们需要的版本即可解决此问题。
因为我这里使用的 elasticsearch 的版本是 6.7.0 , 所以需要指定 spring data elasticsearch 的版本兼容对应的 elasticsearch 版本即可。

项目中原来的依赖如下(只列出es相关依赖),没有指定版本号,使用的是默认的版本号:

        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-elasticsearch</artifactId>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
        </dependency>

修改为如下的配置,即手动指定需要的版本号:

 <properties>
        <spring.data.elasticsearch.version>3.2.1.RELEASE</spring.data.elasticsearch.version>
        <elasticsearch.version>6.7.0</elasticsearch.version>
</properties>
<dependencies>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-elasticsearch</artifactId>
            <version>${spring.data.elasticsearch.version}</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>${elasticsearch.version}</version>
        </dependency>
</dependencies>

通过上面的配置之后,再次启动项目,项目可以正常启动了。


惜鸟
328 声望2.3k 粉丝