[英]Spark NoSuchMethodError on SQLContext.sql (Spark 1.6.0 on Cloudera 5.8.0)
[英]How to resolve Spark library conflict with Cloudera CDH 5.8.0 virtual box
我正在嘗試提交要在Cloudera CDH 5.8.0虛擬框中啟動的作業,並且我正在使用json庫,並且還使用了maven-shade插件來包含對jar文件的依賴關系,以下是我的pom:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>spark</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.11</artifactId>
<version>1.5.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20160810</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<finalName>uber-${project.artifactId}-${project.version}</finalName>
</configuration>
</plugin>
</plugins>
</build>
</project>
提交命令為:
spark-submit --class com.example.spark.SparkParser --master local[*] uber-spark-0.0.1-SNAPSHOT.jar
而且我不斷收到以下異常:
Exception in thread "main" java.lang.NoSuchMethodError:
org.json.JSONTokener.<init>(Ljava/io/InputStream;)
我發現了下面的一小段代碼,可以告訴您從哪個庫中加載了該類:
ClassLoader classloader = org.json.JSONTokener.class.getClassLoader();
URL res = classloader.getResource("org/json/JSONTokener.class");
String path = res.getPath();
System.out.println("Core JSONTokener came from " + path);
輸出如下:
Core JSONTokener came from file:/usr/lib/hive/lib/hive-exec-1.1.0-cdh5.8.0.jar!/org/json/JSONTokener.class
我可以在CDH的虛擬框中找到本地文件,如下所示:
[cloudera@quickstart ~]$ ls -l /usr/lib/hive/lib/hive-exec-1.1.0-cdh5.8.0.jar
-rw-r--r-- 1 root root 19306194 Jun 16 2016 /usr/lib/hive/lib/hive-exec-1.1.0-cdh5.8.0.jar
我什至試圖將json庫設置為“提供”,以將其從jar文件中排除,但仍然是相同的錯誤。
我試圖刪除名為以下目錄的本地jar文件:/usr/lib/hive/lib/hive-exec-1.1.0-cdh5.8.0.jar並且我的代碼正常運行,但是我不確定這是否是正確的解決方案,並且如果刪除該庫會以某種方式傷害cloudera。
因此,如何告訴spark不使用此本地jar文件,而使用“ uber-spark-0.0.1-SNAPSHOT.jar”文件中包含的文件?
不知道為什么以前沒有人回答過你...
您的問題是,運行時類路徑中具有相同庫的兩個不同版本。 一個包含在您的jar中,另一個由Cloudera添加。 JSONTokener中有一個方法在兩個版本之間是不同的(可能在一個版本上不存在,或者簽名已更改),您在代碼中使用了一個版本(這就是代碼編譯的原因),但是在運行時,ClassLoader正在使用其他。
這個問題的簡短答案是,您不能:Java ClassLoader加載路徑中的所有庫,並且當您加載類時,它將加載它找到的第一個庫。 在這種情況下,由Hive運行時提供。
更長的答案:強制使用應用程序隨附的jar的唯一選擇是編輯spark默認值,使其不包含Hive。 現在,我不太確定如何執行此操作,但是我可能會查看/etc/spark/spark-defaults.conf,嘗試禁用Hive或通過Cloudera Manager中的某些方法。
更好的選擇是從項目中刪除jar,將Cloudera Maven存儲庫添加到pom並包含hive-exec-1.1.0-cdh5.8.0作為提供的依賴項,請參閱使用CDH 5 Maven存儲庫以獲取更多信息。這個怎么做。
希望這可以幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.