背景介紹:
當ES中guava庫與hive等組件的庫沖突時,對Elasticsearch庫進行shade,relocate解決庫沖突問題。
當使用"org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"對資源進行重定向后,仍舊報錯,報錯信息:
An SPI class of type org.apache.lucene.codecs.PostingsFormat with name 'Lucene50' does not exist. You need to add the corresponding JAR file supporting this SPI to your classpath. The current classp
根本原因:需要對META-INF/services資源合並。
Java spi機制:
“當服務的提供者,提供了服務接口的一種實現之后,在jar包的META-INF/services/目錄里同時創建一個以服務接口命名的文件。該文件里就是實現該服務接口的具體實現類。而當外部程序裝配這個模塊的時候,就能通過該jar包META-INF/services/里的配置文件找到具體的實現類名,並裝載實例化,完成模塊的注入。 基於這樣一個約定就能很好的找到服務接口的實現類,而不需要再代碼里制定。
jdk提供服務實現查找的一個工具類:java.util.ServiceLoader” 《【java規范】Java spi機制淺談》
解決方法有兩種:
1、Maven配置
<transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer" /> <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/> </transformers>
2、手動在工程的src目錄下創建目錄META-INF/services/ 並手動將上面兩個紅框里的內容做合並,這樣所有路徑都包含了,缺一不可。
參考:
http://stackoverflow.com/questions/35066597/elasticsearch-in-a-runnable-jar-lucene-problems
http://rocketeer.leanote.com/post/dcab93e5bf35