我在EMR步骤中执行一个spark-submit脚本,它将我的超级JAR作为主类,如下所示
spark-submit \
....
--class ${MY_CLASS} "${SUPER_JAR_S3_PATH}"..。等
但是Spark默认加载JAR文件:/usr/lib/spark/jars/Guice-3.0.jar,其中包含com.google.inject.internal.InjectorImpl,这个类也在我的超级jar中的Guice-4.x 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,以便我的代码可以使用打包在Guice-4.x JAR中的InjectorImpl?我还在客户端模式下运行Spark,所以我不能使用spark.driver.userClassPathFirst或spark.executor.userClassPathFirst
发布于 2019-05-22 12:57:58
一种方法是指向您的guice旧版本jar所在的lib,然后将其排除。
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版本,看看有什么可用的。
根据文档,spark的最新版本中包含runtime-environment userClassPathFirst。
spark.executor.userClassPathFirst
spark.driver.userClassPathFirst
要使用它,您可以使用所有应用程序级别的依赖项来创建uber jar。
https://stackoverflow.com/questions/56248875
复制相似问题