升级Spring Boot 2.5.2与Spring Core 5.3.8后遭遇org.elasticsearch.action.ActionType类未找到异常的解决方案咨询
问题背景
你将应用升级到springBootVersion=2.5.2、springCoreVersion=5.3.8后,触发了BeanCreationException,核心异常为java.lang.NoClassDefFoundError: org/elasticsearch/action/ActionType,完整异常堆栈如下:
org.springframework.beans.factory.BeanCreationException: 在类路径资源[org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchDataConfiguration$RestClientConfiguration.class]中定义的名称为'elasticsearchTemplate'的Bean创建失败:通过工厂方法实例化Bean失败;嵌套异常为org.springframework.beans.BeanInstantiationException:无法实例化[org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate]:工厂方法'elasticsearchTemplate'抛出异常;嵌套异常为java.lang.NoClassDefFoundError: org/elasticsearch/action/ActionType
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:658) ~[spring-beans-5.3.8.jar:5.3.8]
...(省略中间重复堆栈信息)
Caused by: java.lang.ClassNotFoundException: org.elasticsearch.action.ActionType
当前你的依赖配置:
implementation "org.springframework.data:spring-data-elasticsearch:4.2.2" implementation "org.elasticsearch:elasticsearch:6.5.4" implementation "org.elasticsearch.client:elasticsearch-rest-client:6.5.4" implementation "org.elasticsearch.client:elasticsearch-rest-high-level-client:6.5.4"
生产环境Elasticsearch版本为6.5.4。
问题核心原因
这是典型的版本依赖不兼容问题:
- Spring Boot 2.5.2默认绑定的
spring-data-elasticsearch:4.2.2是基于Elasticsearch 7.12.x版本开发的,它依赖的客户端API与6.x版本存在显著差异。 - 你引入的Elasticsearch核心库和客户端是6.5.4版本,但
spring-data-elasticsearch:4.2.2初始化ElasticsearchRestTemplate时,会调用7.x版本API专属的org.elasticsearch.action.ActionType类,该类在6.5.4的类路径中不存在,因此抛出类未找到的异常。
解决方案
你有两种可行方案,可根据业务需求选择:
方案一:保留Spring Boot 2.5.2,升级Elasticsearch客户端版本
Elasticsearch客户端支持向前兼容,7.x版本的客户端可以正常连接6.x版本的服务端(仅部分新特性无法使用,基础CRUD、查询功能不受影响)。你可以将Elasticsearch相关依赖升级到与spring-data-elasticsearch:4.2.2匹配的7.12.0版本:
调整后的依赖配置(推荐使用Spring Boot Starter自动管理版本):
// 借助Spring Boot Starter自动维护版本一致性,避免手动版本冲突 implementation "org.springframework.boot:spring-boot-starter-data-elasticsearch" // 若需手动指定版本,需确保与Spring Boot 2.5.2的版本对齐 // implementation "org.springframework.data:spring-data-elasticsearch:4.2.2" // implementation "org.elasticsearch:elasticsearch:7.12.0" // implementation "org.elasticsearch.client:elasticsearch-rest-client:7.12.0" // implementation "org.elasticsearch.client:elasticsearch-rest-high-level-client:7.12.0"
方案二:降级Spring Boot版本,适配Elasticsearch 6.5.4
如果必须严格匹配生产环境的Elasticsearch 6.5.4客户端版本,可以降级Spring Boot和Spring Data Elasticsearch到支持6.x版本的组合:
- Spring Boot 2.1.x系列(示例用2.1.18.RELEASE)对应的
spring-data-elasticsearch:3.2.x,完美支持Elasticsearch 6.2.x到6.8.x版本,与你的生产环境完全兼容。
调整后的配置:
springBootVersion = '2.1.18.RELEASE' springCoreVersion = '5.1.19.RELEASE' implementation "org.springframework.data:spring-data-elasticsearch:3.2.18.RELEASE" implementation "org.elasticsearch:elasticsearch:6.5.4" implementation "org.elasticsearch.client:elasticsearch-rest-client:6.5.4" implementation "org.elasticsearch.client:elasticsearch-rest-high-level-client:6.5.4"
总结
如果希望保留Spring Boot 2.5.2的新特性,优先选择方案一;如果业务要求必须使用6.5.4版本的Elasticsearch客户端,选择方案二降级Spring Boot版本即可解决问题。
内容的提问来源于stack exchange,提问作者Saif Haider

