【问题标题】:How to use multiple versions of a library in Scala?如何在 Scala 中使用多个版本的库?
【发布时间】:2017-12-16 01:13:54
【问题描述】:

我在 Scala 中使用了一个库 A,它依赖于另一个库 Z 的 x.11 版本。

现在,我也在使用一个库 B,它依赖于 Z 的 x.31 版本。

这会导致编译错误,因为我们将有两个版本的库 Z,如何在 scala 的 sbt 中同时使用库 A 和 B?有没有办法指定呢。

【问题讨论】:

标签: scala sbt


【解决方案1】:

如果用较新版本完全替换一个依赖项恰好可行,则 Sparko 的解决方案有效。但是,情况并非总是如此。

如果您想在 sbt-assembly 生成的 uber-jar 中包含两个版本的库,则需要使用着色。请参阅 this post 了解什么是着色以及与之相关的一些缺点的概述。

在 sbt-assembly 的文档 here 中介绍了阴影,但如果你和我一样,他们解释它的方式会让你比开始时更加困惑。有一篇很好的博文,Spark, Uber Jars and Shading with sbt-assembly (waybackmachine link),有助于揭开它的神秘面纱。以下是相关部分:

我可以遮盖我的类型安全配置版本,给它一个不同的 名称以便 Spark 不会在版本之间混淆。我赶紧去了 到我的 build.sbt 文件中,并添加以下代码:

程序集中的assemblyShadeRules := Seq(
ShadeRule.rename("com.typesafe.config.**" -> "my_conf.@1") .inLibrary("com.typesafe" % "config" % "1.3.0") .inProject)

根据文档,这应该将任何类放在 com.typesafe.config 在新包 my_conf 下。

对于您的情况,解决方案是将这样的内容添加到您的 build.sbt 文件中:

assemblyShadeRules in assembly := Seq(
      ShadeRule.rename("com.somecompany.**" -> "my_conf.@1")
      .inLibrary("com.somecompany" % "libraryZ" % "0.11")
      .inProject
    )

【讨论】:

  • 您能否更详细地了解该解决方案的工作原理?第二行的com.somecompany.** 是否应该引用库 A?
【解决方案2】:

在 sbt 中,库之间的冲突是使用冲突管理器配置的。默认情况下,会选择最新版本,但也可以在您的 .sbt 文件中覆盖:

conflictManager := ConflictManager.strict

如果您使用的是 sbt 0.13.6 或更高版本,当您的依赖项之间的二进制版本不兼容时,您会收到警告。在这种情况下,您可以在 sbt 文件中为特定库配置覆盖:

dependencyOverrides += "org.raman" % "Z" % "x.11"

这将强制Z 的解析版本为x.11,但不会直接引入依赖。

【讨论】:

  • 这能回答 OP 的问题吗?他们想知道“我如何在 scala 的 sbt 中同时使用库 A 和 B?” (当然,答案可能是“你不能”)
  • 在运行 sbt 程序集时,由于库有多个版本,它会报错。一种方法是排除其他版本的库,只保留其中一个。冲突管理器也适用于装配吗?
猜你喜欢
  • 2012-12-02
  • 2014-01-16
  • 1970-01-01
  • 2017-02-09
  • 1970-01-01
  • 1970-01-01
  • 2014-06-19
  • 2014-09-27
相关资源
最近更新 更多