问题
- spark程序调用高版本gson方法,集群运行时抛出NoSuchMethod异常,本地执行无问题
- 查看依赖,程序本身并没有依赖老版本的gson。
原因
- spark自带gson,版本为2.2.4。spark任务启动时,会优先加载该版本。程序本身编译集成的gson版本不会被加载。
- 如果代码中使用了更高版本的gson才有的方法和特性,就会抛出异常。
解决方案
使用maven-shade-plugin的relocate功能。该功能将package进行改名成另外一个。程序在运行时,会自动将原package进行改名。
具体方法:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<!-- 设置主类 -->
<mainClass>mainClass</mainClass>
</transformer>
</transformers>
<relocations>
<relocation>
<pattern>com.google.gson</pattern>
<shadedPattern>shaded.com.google.gson</shadedPattern>
</relocation>
</relocations>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<!-- 排除以下文件,防止程序启动时,校验错误 -->
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
然后使用maven package进行打包即可 (注意 shade插件使用该方式进行打包,否则shade插件不生效)