問題與分析
今天把項目的log4j的依賴改成了log4j2的依賴后,發現使用Maven打包時報錯如下:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project cbx-core: Compilation failure
[ERROR] cannot access org.apache.http.annotation.NotThreadSafe
[ERROR] class file for org.apache.http.annotation.NotThreadSafe not found
意思很清楚,找不到類NotThreadSafe
。當我把log4j2改回來log4j后重新打包就不再報錯,很明顯,和log4j2有關。
納悶的是,我先前獨自寫了個測試類是沒問題的,怎么一到項目里使用就報錯了呢?Eclipse里也沒有報錯,看了下pom的依賴層級,也沒發現有什么jar包沖突。百度了下,發現了問題原因。
該問題是因為httpclient和httpcore兩個jar包版本不匹配造成的。由於項目里使用了ElasticSearch,需要httpclient等相關的依賴,其中有兩個依賴如下:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.5</version>
</dependency>
原本在使用log4j的時候,項目可以正常打包,但當改成log4j2的時候,需要使用到httpcore包中的某個注解,但由於在4.4.5
版本的httpcore中舍棄了一些注解,於是就報錯說找不到NotThreadSafe。
根據Apache的jira issue:HDFS-12527來看,里邊的comment提到了:
The problem is that the httpclient and httpcore versions are incompatible.
根據comment來看,httpcore是httpclient的依賴,比較合適的版本應該是4.5.2的httpclient和4.4.4的httpcore。
而從pom的依賴層次看,4.5.2的httpclient本身就是依賴了4.4.4版本的httpcore;但由於項目里偏偏引入更高版本的httpcore,平時固然沒問題,但一旦導入某些jar包譬如log4j2,就會編譯報錯。
解決方法
將httpcore的版本改成4.4.4(低於4.4.5即可),重新進行Maven打包操作,結果編譯成功,順利打包。