如何为cats 0.9.0与2.8.0创建sbt ShadeRule解决版本冲突
解决Scala Play应用中Cats版本冲突的sbt-assembly ShadeRule配置问题
问题背景
基于Scala 2.12(sbt 1.5.5)的Scala Play 2.6应用,使用sbt-assembly 1.2.0打包。应用本身依赖Cats 2.8.0,新增第三方库依赖Cats 0.9.0,引发二进制不兼容的版本冲突。
冲突错误信息
[error] (app / update) found version conflict(s) in library dependencies; some are suspected to be binary incompatible: [error] [error] * org.typelevel:cats-core_2.12:2.8.0 (early-semver) is selected over {0.9.0, 2.2.0} [error] +- org.scala-sbt.temp:temp-resolve-4579dec96ae08171122c66ca210e0186a9f70b99:1.0 (depends on 2.8.0) [error] +- org.typelevel:cats-free_2.12:2.2.0 () (depends on 2.2.0) [error] +- org.typelevel:cats-laws_2.12:0.9.0 () (depends on 0.9.0) [error] +- org.typelevel:cats_2.12:0.9.0 () (depends on 0.9.0) [error] +- org.typelevel:cats-jvm_2.12:0.9.0 () (depends on 0.9.0) [error] +- org.typelevel:cats-free_2.12:0.9.0 () (depends on 0.9.0) [error] [error] * org.typelevel:cats-kernel_2.12:2.8.0 (early-semver) is selected over {2.2.0, 0.9.0} [error] +- org.typelevel:cats-core_2.12:2.8.0 () (depends on 2.8.0) [error] +- org.typelevel:cats-laws_2.12:0.9.0 () (depends on 0.9.0) [error] +- org.typelevel:cats-kernel-laws_2.12:0.9.0 () (depends on 0.9.0) [error] +- org.typelevel:cats-core_2.12:0.9.0 () (depends on 0.9.0) [error] +- org.typelevel:cats_2.12:0.9.0 () (depends on 0.9.0) [error] +- org.typelevel:cats-core_2.12:2.2.0 () (depends on 2.2.0)
失败的配置尝试
尝试编写ShadeRule解决冲突,但配置未生效,尝试.inProject、.inAll均无效:
ThisBuild / assemblyShadeRules := Seq( ShadeRule.rename("org.typelevel.**" -> "shadeTypelevel.@1") .inLibrary( "org.typelevel" % "cats-core_2.12" % "0.9.0", "org.typelevel" % "cats-kernel_2.12" % "0.9.0", "org.typelevel" % "cats-law_2.12" % "0.9.0", "org.typelevel" % "cats_2.12" % "0.9.0", "org.typelevel" % "cats-jvm_2.12" % "0.9.0", "org.typelevel" % "cats-free_2.12" % "0.9.0", "org.typelevel" % "cats-kernel-laws_2.12" % "0.9.0", "org.typelevel" % "cats-macros_2.12" % "0.9.0", ).inProject )
核心困惑:sbt-assembly 0.x可链式调用.inLibrary传入多个模块,但1.x似乎只能调用一次,导致配置失效。
正确解决方案
配置修正要点
- sbt-assembly 1.x的
.inLibrary调用规则:每次只能传入单个模块坐标,多个模块需链式调用多次.inLibrary,而非传入多个参数。 - 修正拼写错误:
cats-law_2.12应为cats-laws_2.12,否则无法匹配目标模块。 - 包命名规范:重命名路径建议使用
shaded.org.typelevel格式,避免与其他包冲突。
修正后的ShadeRule配置
ThisBuild / assemblyShadeRules := Seq( ShadeRule.rename("org.typelevel.**" -> "shaded.org.typelevel.@1") // 逐个指定需要shade的旧版Cats模块 .inLibrary("org.typelevel" % "cats-core_2.12" % "0.9.0") .inLibrary("org.typelevel" % "cats-kernel_2.12" % "0.9.0") .inLibrary("org.typelevel" % "cats-laws_2.12" % "0.9.0") .inLibrary("org.typelevel" % "cats_2.12" % "0.9.0") .inLibrary("org.typelevel" % "cats-jvm_2.12" % "0.9.0") .inLibrary("org.typelevel" % "cats-free_2.12" % "0.9.0") .inLibrary("org.typelevel" % "cats-kernel-laws_2.12" % "0.9.0") .inLibrary("org.typelevel" % "cats-macros_2.12" % "0.9.0") // 可选:直接对引入旧版Cats的业务库应用规则,更精准 // .inLibrary("your-lib-group" % "your-lib-name_2.12" % "your-lib-version") // 避免shade项目自身代码 .inProject )
辅助排查步骤
若仍无法生成依赖树,可临时排除冲突依赖,先确认旧版Cats的引入路径:
// 临时排除第三方库中的旧版Cats libraryDependencies += "your-new-lib-group" % "your-new-lib-name_2.12" % "your-version" excludeAll ExclusionRule(organization = "org.typelevel")
执行sbt dependencyTree查看完整依赖关系,确认后再调整ShadeRule规则。
内容的提问来源于stack exchange,提问作者Chace
相关产品推荐
相关产品推荐

