Guava com.google.common.base.Stopwatch Spark程序在yarn中 MethodNotFound
今天在公司提交一个Spark 读取hive中的数据,写入JanusGraph 的app,自己本地调试没有问题,放入环境中提交到yarn 中时,发现app 跑不起。

yarn 中日志,也比较明显,app引用到 janusGraph 中的 StandardIDPool 找不到StopWatch.class 的方法:createStarted,就是Guava 包中找不到该方法。我自己也把的app depends中的Guava 1.6.0 反编译,那个方法也是存在的。
应用没有跑起来,没法看到yarn 中具体的classpath。于是看了另一个spark 程序的 Environment

发现System classpath 引用了很多低版本的guava包。如果一个一个去替换可能会影响到yarn 本身的运行。
于是发现了 maven 的一个插件 maven-shade-plugin
在spark app 的pom 文件加入了如下代码
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<relocations>
<relocation>
<pattern>com.google.common</pattern>
<shadedPattern>com.shade.google.common</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
打包:mvn package -Dmaven.test.skip=true
maven-shade-plugin 也就是把当前项目中所有引用jar 解压成具体的*.class
然后com.google.com 包名重命名 为 com.shade.google.common
再把当前所有项目 和 项目引用到jar中 到 com.google.com.* 改成 com.shade.google.common
注意:是当前项目 和 项目引用的jar 用到guava 都会改成 com.shade.google.common
对比之前的包 和 现在(新包是jar.bat)这个
![]()
新包是把所有的依赖都打包到一起了,这是不太好的一点。反编译看之前的StandardIDPool(这个Class 是我app引用的JanusGraph依赖)

JanusGraph 把涉及到 com.google.com.* 改成 com.shade.google.common。
提交yarn 是没有问题的。
之后我还发现,如果不用这个maven 插件,直接把所有依赖和当前的项目,直接打包成一个jar 提交到yarn 也是可以跑。
我理解此时的JanusGraph 中 StandardIDPool.class 相当不是引用的jar ,而是当前项目的一部分,和classpath 的jar 冲突不了。具体的原因我继续分析
浙公网安备 33010602011771号