You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Maven Shade Plugin的Apache Spark项目Jackson Databind冲突问题

解决Spark项目中Jackson版本冲突问题

核心原因

你的问题本质是EMR集群自带的旧版Jackson(2.12.7-1)优先级高于你胖JAR中的2.15.2版本。Spark的类加载机制会优先加载集群环境中的系统依赖,而非用户JAR里的依赖,导致版本不匹配触发Scala模块的版本校验错误。

解决方案

1. 使用Maven Shade插件重命名Jackson包(最推荐)

通过Shade的Relocator把Jackson的包路径重命名,彻底隔离用户依赖和集群依赖,从根源避免类冲突。修改你的maven-shade-plugin配置:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.2.4</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
            <configuration>
                <relocations>
                    <!-- 重命名Jackson所有核心包路径 -->
                    <relocation>
                        <pattern>com.fasterxml.jackson</pattern>
                        <shadedPattern>shaded.com.fasterxml.jackson</shadedPattern>
                    </relocation>
                </relocations>
                <transformers>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                        <mainClass>org.example.Main</mainClass>
                    </transformer>
                </transformers>
                <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>

重命名后,你的代码会使用shaded.com.fasterxml.jackson下的类,完全避开集群的旧版Jackson。

2. 强制Spark优先加载用户JAR依赖

提交Spark应用时,添加类加载优先级参数,让用户JAR的依赖先于集群依赖加载:

spark-submit \
  --class org.example.Main \
  --conf spark.driver.userClassPathFirst=true \
  --conf spark.executor.userClassPathFirst=true \
  your-fat-jar.jar

注意:这个参数可能引发其他依赖冲突(比如Spark自身依赖版本不兼容),需要测试验证。

3. 完善Spark依赖的Jackson排除

确保所有Spark相关依赖都彻底排除旧版Jackson,在你的pom.xml中修改Spark依赖:

<!-- Spark Core -->
<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-core_2.13</artifactId>
    <version>3.5.1</version>
    <exclusions>
        <exclusion>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </exclusion>
        <exclusion>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
        </exclusion>
        <exclusion>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
        </exclusion>
        <exclusion>
            <groupId>com.fasterxml.jackson.module</groupId>
            <artifactId>jackson-module-scala_2.13</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<!-- Spark SQL -->
<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-sql_2.13</artifactId>
    <version>3.5.1</version>
    <exclusions>
        <exclusion>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </exclusion>
        <exclusion>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
        </exclusion>
        <exclusion>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
        </exclusion>
        <exclusion>
            <groupId>com.fasterxml.jackson.module</groupId>
            <artifactId>jackson-module-scala_2.13</artifactId>
        </exclusion>
    </exclusions>
</dependency>

这样可以确保项目不会引入Spark传递的旧版Jackson。

4. EMR集群层面调整(可选)

如果上述方法仍无效,可以通过EMR Bootstrap动作修改集群的Spark依赖:

  • 在集群启动时,替换/usr/lib/spark/jars下的旧版Jackson JAR为你需要的2.15.2版本
  • 或者在spark-defaults.conf中添加spark.driver.extraClassPath和spark.executor.extraClassPath,指定你的Jackson JAR路径

验证方法

打包后,使用jar tf your-fat-jar.jar查看是否存在shaded/com/fasterxml/jackson路径下的类;运行应用时,添加日志参数-Dorg.slf4j.simpleLogger.defaultLogLevel=debug,查看类加载路径,确认加载的是你打包的Jackson版本。

内容的提问来源于stack exchange,提问作者prashantjerk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 23:54:56