簡體   English   中英

如何解決與Cloudera CDH 5.8.0虛擬盒的Spark庫沖突

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM