强制 java jar 不在 EMR 上使用类路径包

Posted

技术标签:

【中文标题】强制 java jar 不在 EMR 上使用类路径包【英文标题】:Force java jar to not use classpath packages on EMR 【发布时间】:2019-05-22 09:11:03 【问题描述】:

我正在尝试在 EMR 上通过 spark-submit 运行一个胖罐子。我遇到了与包依赖项相关的问题。这个项目依赖于我在build.sbt 中包含的google adwords 库。问题是google adwords 库内部依赖于一个名为commons-configuration 1.10 版的包,但是当我通过spark-submit 在EMR 上运行这个jar 时,它通过yarn scheduler 运行,使用了这个包的1.6 版(commons-configuration)因为它是 EMR 集群上 CLASSPATH 的一部分。我收到以下错误

java.lang.NoSuchMethodError: org.apache.commons.configuration.MapConfiguration

我尝试使用 --jarsspark-submit 选项显式传递依赖 jar

spark-submit --name my-awesome-spark-job --deploy-mode cluster --class package.path.to.my.Main --jars s3://jar-bucket/jars/commons-configuration-1.10.jar s3://code-bucket/jars/spark-code.jar

这样做仍然会给我同样的错误,因为无论如何都在使用 CLASSPATH 中的旧版本包。 我想强制我的 jar 将依赖项包含在 fat jar 中,并将它们显式用于某些库,例如 google adwords library here。谢谢。

【问题讨论】:

【参考方案1】:

您可以尝试遮蔽您正在使用的依赖项,并且在集群上有旧版本可用。

你用什么来构建 jar?我已经在 sbt 中使用了这个策略 https://github.com/sbt/sbt-assembly#shading

但是maven也有一个shade插件:https://maven.apache.org/plugins/maven-shade-plugin/

【讨论】:

我正在使用 sbt-assembly 来构建 jar。我尝试使用ShadeRule.rename("com.google.**" -> "shade.com.google.@1").inAll 对谷歌库进行着色,但问题是这个库在内部依赖于其他一些在集群上有旧版本的库。所以这对我没有帮助。 您的解决方案有效,我为 commons-configuration 库添加了阴影,一切都像魅力一样。万分感谢!我添加了以下行ShadeRule.rename("org.apache.commons.configuration.**" -> "shade.org.apache.commons.configuration.@1").inAll

以上是关于强制 java jar 不在 EMR 上使用类路径包的主要内容,如果未能解决你的问题,请参考以下文章

Tools.jar 不在 Android Studio 类路径中

使用自定义文件配置 EMR 节点

pyspark 代码在控制台中工作,但不在 zeppelin 中

Java - 类存在两次(在类路径和应用程序 jar 上)。 LinkageError:ClassCastException

加jar包啥时候需要添加类路径

动态加载java类文件的方法