背景
由于前段时间出现的 log4j2 的漏洞,项目中默认用的是logback日志组件,所以想着在 pom.xml 中排除掉了 log4j2 的相关依赖应该影响不大。
现象
在日志文件中有看到有许多这样的错误日志:
java.lang.NoClassDefFoundError: Could not initialize class org.elasticsearch.search.builder.SearchSourceBuilder
at org.elasticsearch.action.search.SearchRequest.<init>(SearchRequest.java:122)
at org.springframework.data.elasticsearch.core.RequestFactory.prepareSearchRequest(RequestFactory.java:1098)
at org.springframework.data.elasticsearch.core.RequestFactory.searchRequest(RequestFactory.java:1061)
at org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate.searchScrollStart(ElasticsearchRestTemplate.java:268)
一开始以为是没有这个 SearchSourceBuilder 类,就去代码里查找,发现这个类其实存在的。最后发现服务启动后第一次报了一个这样的错误:
java.lang.NoClassDefFoundError: org/apache/logging/log4j/LogManager
at org.elasticsearch.search.builder.SearchSourceBuilder.<clinit>(SearchSourceBuilder.java:84)
at org.elasticsearch.action.search.SearchRequest.<init>(SearchRequest.java:122)
at org.springframework.data.elasticsearch.core.RequestFactory.prepareSearchRequest(RequestFactory.java:1098)
at org.springframework.data.elasticsearch.core.RequestFactory.searchRequest(RequestFactory.java:1061)
at org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate.searchScrollStart(ElasticsearchRestTemplate.java:268)
结论
根据服务启动的报第一次这个java.lang.NoClassDefFoundError可知,jvm本来是要加载 SearchSourceBuilder 这个类,这个类初始化时却依赖了 log4j 的 API,而 log4j 的依赖包被我们去掉了,导致最后类 SearchSourceBuilder 一直无法初始化。
其实最后我想表达的是:
- java.lang.NoClassDefFoundError: org/apache/logging/log4j/LogManager 是虚拟机找不到这个类。
- java.lang.NoClassDefFoundError: Could not initialize class org.elasticsearch.search.builder.SearchSourceBuilder 则表示这个类无法初始化,而非虚拟机找不到这个类。
解决方案
重新依赖log4j2包并升级至最新版本。