IncompatibleClassChangeError when 运行 spark from (spring) servlet
IncompatibleClassChangeError when running spark from (spring) servlet
当 运行 来自 (spring) 网络应用程序的简单 spark 作业时,我得到一个 IncompatibleClassChangeError
。这可能是由于一些不兼容的依赖项,但我找不到哪个。
简单来说,this is the issue有异常堆栈。
这里是the failing code:
// file conversion with spark
// --------------------------
JavaRDD<String> inputRdd = sparkContext.textFile(inputFile).cache();
Function fct = new Function<String,String>() {
@Override
public String call(String line) throws Exception {
return line.toUpperCase();
}
};
JavaRDD<Strineg> outputRdd = inputRdd.map(fct); // *** fail ***
outputRdd.saveAsTextFile(outputDir);
调用的
@RequestMapping(method = RequestMethod.GET, value="/upper")
public @ResponseBody boolean upper(@RequestParam(required = true) String inputFile,
@RequestParam(required = true) String outputDir,
@RequestParam(required = false) String master,
@RequestParam(required = false) String namenode) {
if(master==null) master = "local";
SparkUpper.upper(inputFile, outputDir, master, namenode);
return true;
}
<dependencies>
<!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- spark & hadoop -->
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.10</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-core</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.5.2</version>
</dependency>
</dependencies>
奇怪的是,基本上做同样的事情,具有相同的 spark 依赖关系,但从 servlet 调用,如 this project 中那样工作正常。
任何想法将不胜感激。
在尝试使用 mvn dependency:tree -Dverbose
来调查依赖冲突后发现了太多依赖冲突,我找到了一个实用的解决方案:
将 war 中包含的 Maven 依赖项替换为我曾经 运行 我的 previous non-spring code.
的 spark-assembly-1.1.1-hadoop2.4.0.jar
实践中:
在本地 maven 中安装 spark-assembly jar:
mvn install:install-file \
-Dfile=$SPARK_HOME/lib/spark-assembly-1.1.1-hadoop2.4.0.jar \
-DgroupId=org.apache.spark -DartifactId=spark-assembly-jar \
-Dversion=1.1.1 -Dpackaging=jar
将其包含在 Maven 依赖项中:
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-assembly-jar</artifactId>
<version>1.1.1</version>
</dependency>
通过将 <scope>provided</scope>
添加到 spark-core
、hadoop-core
和 hadoop-client
,从 war 中删除 spark 和 hadoop jar。 =20=]
据我了解,冲突可能发生在 spark 和 hadoop 依赖项之间,而不是来自 spark/hadoop vs spring。但这可以通过使用包含一起构建的所有内容的 spark-assembly jar 来绕过。
这不是一个非常令人满意的解决方案,它添加了 140MB 的 jar 依赖项,但它确实有效。最好找到一组合适的 spark/hadoop 实际相互配合的依赖项。
此外,我可以寻找一种方法将此 spark-assembly
jar 包含在 servlet 容器的类路径中,而不是包含在 war.
中
当 运行 来自 (spring) 网络应用程序的简单 spark 作业时,我得到一个 IncompatibleClassChangeError
。这可能是由于一些不兼容的依赖项,但我找不到哪个。
简单来说,this is the issue有异常堆栈。
这里是the failing code:
// file conversion with spark
// --------------------------
JavaRDD<String> inputRdd = sparkContext.textFile(inputFile).cache();
Function fct = new Function<String,String>() {
@Override
public String call(String line) throws Exception {
return line.toUpperCase();
}
};
JavaRDD<Strineg> outputRdd = inputRdd.map(fct); // *** fail ***
outputRdd.saveAsTextFile(outputDir);
调用的
@RequestMapping(method = RequestMethod.GET, value="/upper")
public @ResponseBody boolean upper(@RequestParam(required = true) String inputFile,
@RequestParam(required = true) String outputDir,
@RequestParam(required = false) String master,
@RequestParam(required = false) String namenode) {
if(master==null) master = "local";
SparkUpper.upper(inputFile, outputDir, master, namenode);
return true;
}
<dependencies>
<!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- spark & hadoop -->
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.10</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-core</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.5.2</version>
</dependency>
</dependencies>
奇怪的是,基本上做同样的事情,具有相同的 spark 依赖关系,但从 servlet 调用,如 this project 中那样工作正常。
任何想法将不胜感激。
在尝试使用 mvn dependency:tree -Dverbose
来调查依赖冲突后发现了太多依赖冲突,我找到了一个实用的解决方案:
将 war 中包含的 Maven 依赖项替换为我曾经 运行 我的 previous non-spring code.
的spark-assembly-1.1.1-hadoop2.4.0.jar
实践中:
在本地 maven 中安装 spark-assembly jar:
mvn install:install-file \ -Dfile=$SPARK_HOME/lib/spark-assembly-1.1.1-hadoop2.4.0.jar \ -DgroupId=org.apache.spark -DartifactId=spark-assembly-jar \ -Dversion=1.1.1 -Dpackaging=jar
将其包含在 Maven 依赖项中:
<dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-assembly-jar</artifactId> <version>1.1.1</version> </dependency>
通过将
<scope>provided</scope>
添加到spark-core
、hadoop-core
和hadoop-client
,从 war 中删除 spark 和 hadoop jar。 =20=]
据我了解,冲突可能发生在 spark 和 hadoop 依赖项之间,而不是来自 spark/hadoop vs spring。但这可以通过使用包含一起构建的所有内容的 spark-assembly jar 来绕过。
这不是一个非常令人满意的解决方案,它添加了 140MB 的 jar 依赖项,但它确实有效。最好找到一组合适的 spark/hadoop 实际相互配合的依赖项。
此外,我可以寻找一种方法将此 spark-assembly
jar 包含在 servlet 容器的类路径中,而不是包含在 war.