依賴衝突:NoSuchMethodError,ClassNotFoundException
當使用者應用於Spark本身依賴同一個庫時可能會發生依賴衝突,導致程式奔潰。依賴衝突表現為在執行中出現NoSuchMethodError或者ClassNotFoundException的異常或者其他與類載入相關的JVM異常。
此時,若能確定classpath中存在這個包,則錯誤是因為classpath中存在2個不同版本的jar包了,比如常見的log4j,你在classpath中新增了log4j.jar,而spark的lib目錄中也有log4j.jar,而且這2個jar包版本不一致的話,就會出現依賴衝突問題。
解決辦法有2種:
(1)修改你的應用,使其使用的依賴庫的版本與Spark所使用的相同。
(2)使用稱為shading的方式打包你的應用。使用maven-shade-plugin外掛進行高階配置來支援這種打包方式。shading可以讓你以另一種名稱空間保留衝突的包,並自動重寫應用的程式碼使得它們使用重新命名後的版本。這種技術有些簡單粗暴,不過對於解決執行時依賴衝突的問題非常有效。
關於maven-shade-plugin外掛的詳細介紹請參閱:http://www.jianshu.com/p/7a0e20b30401#
maven-shade-plugin外掛的官方介紹:http://maven.apache.org/plugins/maven-shade-plugin/index.html
Java 工程經常會遇到第三方Jar 包衝突,使用 maven-shade-plugin 解決 jar 或類的多版本衝突。 maven-shade-plugin 在打包時,可以將專案中依賴的 jar 包中的一些類檔案打包到專案構建生成的 jar 包中,在打包的時候把類重新命名。
舉例如下:
下面的配置將org.codehaus.plexus.util jar 包重新命名為org.shaded.plexus.util。
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>2.4.3</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <relocations> <relocation> <pattern>org.codehaus.plexus.util</pattern> <shadedPattern>org.shaded.plexus.util</shadedPattern> <excludes> <exclude>org.codehaus.plexus.util.xml.Xpp3Dom</exclude> <exclude>org.codehaus.plexus.util.xml.pull.*</exclude> </excludes> </relocation> </relocations> </configuration> </execution> </executions> </plugin> </plugins> </build>