如何Shade Fat Jar依赖中的包解决SBT项目类版本冲突问题
解决方案
核心问题原因
你之前的shade配置不生效主要有两个原因:
- 仅指定
.inLibrary未加.inAll,只重命名了Sparkling Water包内的冲突类,没有同步修改包内对这些类的调用引用,运行时还是会找原始包名的类 - 仅shade了
com.google.api.services.storage单个包,没有覆盖整个Google生态依赖栈,导致后续出现opencensus等关联依赖的版本冲突
正确配置方案
方案一:Shade Sparkling Water内的所有冲突依赖
直接重命名Sparkling Water中所有Google相关包,保证gcs-connector的原生依赖版本优先生效:
assemblyShadeRules in assembly ++= Seq( ShadeRule.rename("com.google.api.**" -> "shade.h2o.@1") .inLibrary("ai.h2o" % "sparkling-water-package_你的Scala版本" % "你的Sparkling Water版本") .inAll, ShadeRule.rename("io.opencensus.**" -> "shade.h2o.opencensus.@1") .inLibrary("ai.h2o" % "sparkling-water-package_你的Scala版本" % "你的Sparkling Water版本") .inAll )
方案二:全量Shade gcs-connector及其依赖栈
如果不想改动Sparkling Water的包,就把gcs-connector的所有关联依赖全部shade,和Sparkling Water的类完全隔离:
assemblyShadeRules in assembly ++= Seq( ShadeRule.rename("com.google.**" -> "shade.gcs.@1") .inLibrary("com.google.cloud.bigdataoss" % "gcs-connector" % "hadoop3-2.2.2") .inAll, ShadeRule.rename("io.opencensus.**" -> "shade.gcs.opencensus.@1") .inLibrary("com.google.cloud.bigdataoss" % "gcs-connector" % "hadoop3-2.2.2") .inAll )
额外必加合并策略
避免打包时出现重复文件冲突:
assemblyMergeStrategy in assembly := { case PathList("META-INF", "services", _*) => MergeStrategy.concat case PathList("META-INF", xs @ _*) => MergeStrategy.discard case x => MergeStrategy.first }
集群运行额外配置
如果是提交到Spark集群运行,需要配置优先加载用户自定义的类,避免集群自带的类加载优先级更高:
spark-submit \ --conf spark.driver.userClassPathFirst=true \ --conf spark.executor.userClassPathFirst=true \ # 其余你的提交参数
内容的提问来源于stack exchange,提问作者bachr
相关产品推荐
相关产品推荐

