SBT多模块项目执行assembly打包时Spark重复类冲突问题求助
问题原因
多个Spark组件包(spark-core、spark-launcher、spark-tags等)以及第三方unused依赖包中都存在同名的org/apache/spark/unused/UnusedStubClass.class文件,当前配置的合并规则没有覆盖该路径,导致sbt-assembly插件无法判定合并方式报错。
具体解决步骤
1. 调整assembly合并策略,增加UnusedStubClass的处理规则
修改你build.sbt中的assemblySettings块,新增针对该类的合并规则,选任意一个版本保留即可(该类是空占位类,不影响业务功能):
lazy val assemblySettings = Seq( assemblyJarName in assembly := name.value + ".jar", assemblyMergeStrategy in assembly := { // 新增:处理UnusedStubClass冲突 case PathList("org", "apache", "spark", "unused", "UnusedStubClass.class") => MergeStrategy.first case PathList("org.apache.spark", "spark-core_2.11", xs @ _*) => MergeStrategy.last case PathList("META-INF", xs @ _*) => MergeStrategy.discard case "application.conf" => MergeStrategy.concat case x => val oldStrategy = (assemblyMergeStrategy in assembly).value oldStrategy(x) } )
2. 优化Spark依赖配置(可选,建议配置)
业务代码一般运行在已部署Spark的集群环境,集群本身已提供Spark相关依赖,可给Spark依赖加上provided标记,打包时不会把Spark相关jar包打进assembly包,从根源减少这类冲突,同时大幅缩小最终jar包体积:
修改依赖定义部分:
lazy val dependencies = new { val hivejdbc="org.apache.hive" % "hive-jdbc" % "0.13.0" % "provided" val spark23V = "2.3.0.cloudera3" val spark24V="2.4.3" // 增加provided标记 val spark23="org.apache.spark" %% "spark-core" % spark23V % "provided" val spark24="org.apache.spark" %% "spark-core" % spark24V % "provided" }
3. 修复现有配置语法错误
你当前的build.sbt存在语法遗漏,会触发额外编译报错,找到common项目settings中的这一行:
dependencyOverrides += "com.fasterxml.jackson.module" %% "jackson-module-scala" %
补全版本号和其他jackson包对齐即可:
dependencyOverrides += "com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.8.7"
验证
修改完成后重新执行multi1/assembly或者multi2/assembly即可正常打包。
内容的提问来源于stack exchange,提问作者Akhil
相关产品推荐
相关产品推荐

