前言
因為項目需要,最近在學(xué)習(xí)elasticsearch,在使用elasticsearch Java 客戶端時,出現(xiàn)了寫問題,主要就是報各種的
NoClassDefFoundError
如:
java.lang.NoClassDefFoundError: org/elasticsearch/xcontent/ToXContentObject
,出現(xiàn)這種 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客戶端進(jìn)行對elasticsearch的操作了,但是如下執(zhí)行會直接報錯 :
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中發(fā)現(xiàn)了問題所在 [idea右側(cè)菜單欄的Maven Dependencies ] 發(fā)現(xiàn)我的
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中含有的給替換了。文章來源:http://www.zghlxwxcb.cn/news/detail-400998.html
解決:在 demo 工程的 pom 中 聲明 elasticsearch.version
,也就是上述案例代碼中的 注釋給打開,然后依賴?yán)镆迷摪姹咎柤纯?。注意:這里聲明版本的用詞要和 spring-boot-starter-parent 含有的依賴聲明的版本用詞要一致文章來源地址http://www.zghlxwxcb.cn/news/detail-400998.html
到了這里,關(guān)于解決maven 父工程依賴傳遞導(dǎo)致的 java.lang.NoClassDefFoundError: org/elasticsearch/xcontent/ToXContentObject的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!