前言
因为项目需要,最近在学习elasticsearch,在使用elasticsearch Java 客户端时,出现了写问题,主要就是报各种的
NoClassDefFoundError
如:
java.lang.NoClassDefFoundError: org/elasticsearch/xcontent/ToXContentObject
,出现这种 NoClassDefFoundError 的问题基本上就是maven 依赖错误或者版本不对,于是顺着这个思路排查,摸到了问题所在。
案例描述
在尝试使用 elasticsearch-rest-high-level-client
客户端 7.17.4版本。
项目的依赖: elasticsearch-demo -> demo -> spring-boot-starter-parent :2.2.10.RELEASE
父工程demo的pom
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<modules>
<module>elasticsearch-demo</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.10.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
<!-- <elasticsearch.version>7.17.4</elasticsearch.version> -->
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.17.4</version>
<!-- <version>${elasticsearch.version}</version> -->
</dependency>
</dependencies>
</dependencyManagement>
........ 省略 ......
</project>
子工程elasticsearch-demo 的 pom
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>demo</artifactId>
<groupId>com.example</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>elasticsearch-demo</artifactId>
<groupId>com.example</groupId>
<version>0.0.1-SNAPSHOT</version>
<name>elasticsearch-demo</name>
<dependencies>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>
</dependencies>
........ 省略 ......
</project>
使用案例
本以为按照如上配置,就能安心使用java客户端进行对elasticsearch的操作了,但是如下执行会直接报错 :
java.lang.NoClassDefFoundError: org/elasticsearch/xcontent/ToXContentObject
/**
* @author lvzb
* @date 2022/12/05 13:53
**/
@Slf4j
public class ElasticSearchTest {
@Test
void connectEs() throws IOException {
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(
new HttpHost("localhost", 9200, "http")
));
GetIndexRequest request = new GetIndexRequest("index");
boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
// 索引是否存在
System.out.println(exists);
client.close();
}
}
java.lang.NoClassDefFoundError: org/elasticsearch/xcontent/ToXContentObject
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)
at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)
at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:802)
at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:700)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:623)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at com.example.redis.demo.config.ElasticSearchTest.connectEs(ElasticSearchTest.java:70)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:675)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
........ 省略 ......
Caused by: java.lang.ClassNotFoundException: org.elasticsearch.xcontent.ToXContentObject
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 73 more
顺着异常的类,在elasticsearch-demo的Dependencies中发现了问题所在 [idea右侧菜单栏的Maven Dependencies ] 发现我的
org.elasticsearch.client:elasticsearch-rest-high-level-client:7.17.4
下竟然存在一个org.elasticsearch:elasticsearch:6.8.12
而且IDEA没有任何报错和依赖冲突的提示,这是为何?原来是demo 依赖的 父工程
spring-boot-starter-parent :2.2.10.RELEASE
他里面含有org.elasticsearch:elasticsearch:6.8.12
被带过来了,而且竟然直接将我们在 demo 显示声明的 7.17.4中含有的给替换了。文章来源:https://www.toymoban.com/news/detail-400998.html
解决:在 demo 工程的 pom 中 声明 elasticsearch.version
,也就是上述案例代码中的 注释给打开,然后依赖里引用该版本号即可。注意:这里声明版本的用词要和 spring-boot-starter-parent 含有的依赖声明的版本用词要一致文章来源地址https://www.toymoban.com/news/detail-400998.html
到了这里,关于解决maven 父工程依赖传递导致的 java.lang.NoClassDefFoundError: org/elasticsearch/xcontent/ToXContentObject的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!