什么时候在 Scala 中使用 SBT 和 Ivy 模糊地选择了具有相同定义和类路径的两个类?

Posted

技术标签:

【中文标题】什么时候在 Scala 中使用 SBT 和 Ivy 模糊地选择了具有相同定义和类路径的两个类?【英文标题】:When are two classes with same definition and classpath chosen ambiguously in Scala with SBT and Ivy? 【发布时间】:2020-10-15 01:41:24 【问题描述】:

在 Scala 中,使用 sbt,我很好奇如果我能:

    在两个不同名称的库中定义两个具有相同名称、定义和类路径的不同类(假设 case class User(name: String, age: Int) 在两个地方,但一个有require(age >= 0)) 依赖build.sbt 中的这两个库 在成功编译并通过测试的代码中引用该类 将该代码发布为库,然后在其他地方运行

我的具体问题是,这些类在什么时候被模棱两可地选择了?也就是说,在编译、发布和应用程序启动过程的什么时候,流行的类可能会在一个定义和其他的?

这适用于 Play Framework 应用程序,但我不认为它有什么不同。这也适用于 SBT v0.13,它使用 Ivy 进行依赖管理。

【问题讨论】:

【参考方案1】:

假设类路径中存在两个具有完全相同的完全限定名称的类,那么加载哪个类取决于它们在类路径中出现的顺序。我们可以通过执行看到Compileclasspath上的顺序

show Compile / fullClasspath

比如说项目multi1依赖common1common2,那么在下面的场景中

sbt:multi1> show Compile / fullClasspath
[info] * Attributed(/Users/mario_galic/code/***/sbt-multi-project-example/multi1/target/scala-2.12/classes)
[info] * Attributed(/Users/mario_galic/code/***/sbt-multi-project-example/common2/target/scala-2.12/classes)
[info] * Attributed(/Users/mario_galic/code/***/sbt-multi-project-example/common1/target/scala-2.12/classes)

类表单common2 将被加载,因为它在类路径上位于common1 之前。我们可以类似地检查Runtime类路径上的顺序

show Runtime / fullClasspath

我相信没有什么比开箱即用的顺序优先级更智能的了。

附带说明一下,sbt 确实提供了eviction warnings,以防同一库的不同版本得到解决。

【讨论】:

以上是关于什么时候在 Scala 中使用 SBT 和 Ivy 模糊地选择了具有相同定义和类路径的两个类?的主要内容,如果未能解决你的问题,请参考以下文章

使用外部常春藤进行 sbt 构建

SBT 如何为特定的 groupid 禁用 Ivy 缓存

IDEA中使用SBT构建SCALA项目

如何设置 IntelliJ Idea Scala 项目以识别本地 Ivy2 缓存?

ivy.xml 的 SBT 下载错误,尽管它存在

[至逝去的一年]修改IntelliJ IDEA修改系统缓存目录,修改sbt的.sbt和.ivy2