从EMR中的Spark默认类路径中删除JAR

时间:2019-05-22 03:23:57

标签: apache-spark amazon-emr spark-submit

我正在以我的超级JAR为主要类的EMR步骤中执行spark-submit脚本,例如

  spark-submit \
    ....
    --class ${MY_CLASS} "${SUPER_JAR_S3_PATH}"

...等等

但Spark默认情况下会加载jar文件:/usr/lib/spark/jars/guice-3.0.jar,其中包含com.google.inject.internal.InjectorImpl,该类也在Guice-4.x中我的超级JAR中的jar。我的服务正在启动时,这会导致java.lang.IllegalAccessError

我尝试在spark-submit中设置一些Spark conf,以将我的超级jar放在类路径中,希望在Spark加载guice-3.0.jar之前先加载它。看起来像:

--jars "${ASSEMBLY_JAR_S3_PATH}" \
 --driver-class-path "/etc/hadoop/conf:/etc/hive/conf:/usr/lib/hadoop-lzo/lib/*:/usr/share/aws/aws-java-sdk/*:/usr/share/aws/emr/emrfs/conf:/usr/share/aws/emr/emrfs/lib/*:/usr/share/aws/emr/emrfs/auxlib/*:${SUPER_JAR_S3_PATH}" \
 --conf spark.executor.extraClassPath="/etc/hadoop/conf:/etc/hive/conf:/usr/lib/hadoop-lzo/lib/*:/usr/share/aws/aws-java-sdk/*:/usr/share/aws/emr/emrfs/conf:/usr/share/aws/emr/emrfs/lib/*:/usr/share/aws/emr/emrfs/auxlib/*:${SUPER_JAR_S3_PATH}" \

但这会导致相同的错误。

是否有一种方法可以从默认的Spark类路径中删除该guice-3.0.jar,以便我的代码可以使用InjectorImpl JAR中打包的Guice-4.x?我也在客户端模式下运行Spark,因此无法使用spark.driver.userClassPathFirstspark.executor.userClassPathFirst

1 个答案:

答案 0 :(得分:0)

一种方法是指向lib您的guice旧版jar所在的库,然后将其排除。

spark-submit的示例shell脚本:

export latestguicejar='your path to latest guice jar'

   #!/bin/sh
    # build all other dependent jars in OTHER_JARS

JARS=`find /usr/lib/spark/jars/ -name '*.jar'`
OTHER_JARS=""
   for eachjarinlib in $JARS ; do    
if [ "$eachjarinlib" != "guice-3.0.jar" ]; then
       OTHER_JARS=$eachjarinlib,$OTHER_JARS
fi
done
echo ---final list of jars are : $OTHER_JARS
echo $CLASSPATH

spark-submit --verbose --class <yourclass>
... OTHER OPTIONS
--jars $OTHER_JARS,$latestguicejar,APPLICATIONJARTOBEADDEDSEPERATELY.JAR

另请参阅holdens answer。检查您的Spark版本,可以使用什么。

根据文档runtime-environment userClassPathFirst的最新版本提供了spark。

spark.executor.userClassPathFirst
spark.driver.userClassPathFirst

为此,您可以使uber jar具有所有应用程序级别的依赖关系。