首页 > 解决方案 > 从 EMR 中的 Spark 默认类路径中删除 JAR

问题描述

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

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

... ETC

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

我尝试在 中设置一些 Spark confspark-submit以将我的超级 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}" \

但这会导致相同的错误。

有没有办法guice-3.0.jar从默认的 spark 类路径中删除它,以便我的代码可以使用JARInjectorImpl中打包的那个?Guice-4.x我也在客户端模式下运行 Spark,所以我不能使用spark.driver.userClassPathFirstspark.executor.userClassPathFirst

标签: apache-sparkamazon-emrspark-submit

解决方案


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

示例 shell 脚本spark-submit

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

另见霍顿斯的回答。检查你的 spark 版本有什么可用的。

根据 docs运行时环境 userClassPathFirst ,截至今天,最新版本的 spark 中存在运行时环境。

spark.executor.userClassPathFirst
spark.driver.userClassPathFirst

为此,您可以使用所有应用程序级别的依赖项制作 uber jar。


推荐阅读