1. 库依赖

库依赖 

本页假设您已阅读了之前的入门页面,特别是构建定义作用域任务图

库依赖可以以两种方式添加

  • 非托管依赖是放在 lib 目录中的 jar 文件
  • 托管依赖是在构建定义中配置的,并从仓库自动下载

非托管依赖 

大多数人使用托管依赖而不是非托管依赖。但非托管依赖在开始时可能更简单。

非托管依赖的工作原理如下:将 jar 文件添加到 lib 中,它们将被放在项目类路径上。就这么简单!

您也可以将测试 jar 文件(例如 ScalaCheckSpecs2ScalaTest)放在 lib 中。

lib 中的依赖项将被放在所有类路径上(对于 compiletestrunconsole)。如果您想更改其中一个的类路径,例如,您可以调整 Compile / dependencyClasspathRuntime / dependencyClasspath

要使用非托管依赖,不需要在 build.sbt 中添加任何内容,尽管如果您想使用不同的目录而不是 lib,可以更改 unmanagedBase 密钥。

要使用 custom_lib 而不是 lib

unmanagedBase := baseDirectory.value / "custom_lib"

baseDirectory 是项目的根目录,因此在这里您使用特殊方法 value 更改 unmanagedBase,具体取决于 baseDirectory,如 任务图 中所述。

还有一个 unmanagedJars 任务,它列出来自 unmanagedBase 目录的 jar 文件。如果您想使用多个目录或执行其他复杂的操作,则可能需要将整个 unmanagedJars 任务替换为执行其他操作的任务,例如,无论 lib 目录中的文件如何,都清空 Compile 配置的列表

Compile / unmanagedJars := Seq.empty[sbt.Attributed[java.io.File]]

托管依赖 

sbt 使用 Coursier 来实现托管依赖,因此如果您熟悉 Coursier、Apache Ivy 或 Maven,您将不会遇到太多麻烦。

libraryDependencies 密钥 

大多数情况下,您只需在设置 libraryDependencies 中列出您的依赖项。您也可以编写 Maven POM 文件或 Ivy 配置文件来外部配置您的依赖项,并让 sbt 使用这些外部配置文件。您可以了解有关此处的更多信息。

声明依赖项看起来像这样,其中 groupIdartifactIdrevision 是字符串

libraryDependencies += groupID % artifactID % revision

或者像这样,其中 configuration 可以是字符串或 Configuration 值(例如 Test

libraryDependencies += groupID % artifactID % revision % configuration

libraryDependenciesKeys 中声明如下

val libraryDependencies = settingKey[Seq[ModuleID]]("Declares managed dependencies.")

% 方法从字符串创建 ModuleID 对象,然后您将这些 ModuleID 添加到 libraryDependencies 中。

当然,sbt(通过 Coursier)必须知道从哪里下载模块。如果您的模块位于 sbt 附带的默认仓库之一,则这将正常工作。例如,Apache Derby 位于标准 Maven2 仓库中

libraryDependencies += "org.apache.derby" % "derby" % "10.4.1.3"

如果您在 build.sbt 中输入它,然后 update,sbt 应该将 Derby 下载到 Coursier 缓存 中。(顺便说一句,updatecompile 的依赖项,因此大多数情况下无需手动键入 update。)

当然,您也可以使用 ++= 一次添加多个依赖项

libraryDependencies ++= Seq(
  groupID % artifactID % revision,
  groupID % otherID % otherRevision
)

在极少数情况下,您也可能发现使用 :=libraryDependencies 的原因。

使用 %% 获取正确的 Scala 版本 

如果您使用 organization %% moduleName % version 而不是 organization % moduleName % version(区别在于 organization 后的双 %%),sbt 将将您的项目的二进制 Scala 版本添加到构件名称中。这只是一个快捷方式。您可以在没有 %% 的情况下编写它

libraryDependencies += "org.scala-stm" % "scala-stm_2.13" % "0.9.1"

假设您构建的 scalaVersion2.13.12,则以下内容是相同的(请注意 "org.scala-stm" 后的双 %%

libraryDependencies += "org.scala-stm" %% "scala-stm" % "0.9.1"

其想法是,许多依赖项都针对多个 Scala 版本进行了编译,您希望获取与您的项目匹配的版本以确保二进制兼容性。

有关这方面的更多详细信息,请参阅交叉构建

Ivy 修订版本 

organization % moduleName % version 中的 version 不一定是单个固定版本。Ivy 可以根据您指定的约束选择模块的最新修订版本。而不是像 "1.6.1" 这样的固定修订版本,您指定 "latest.integration""2.9.+""[1.0,)"。有关详细信息,请参阅Ivy 修订版本 文档。

有时使用 Maven “版本范围”来指定依赖项(传递或其他),例如 [1.3.0,)。如果在构建中声明了依赖项的特定版本,并且它满足范围,则 sbt 将使用指定的版本。否则,Coursier 可以访问互联网以查找最新版本。这会导致令人惊讶的行为,即有效版本会随着时间的推移而不断变化,即使有一个满足范围条件的库的指定版本。

如果构建中找到了一个令人满意的版本,则 Maven 版本范围将被其下限替换,以便使用该版本。您可以使用 JVM 标志 -Dsbt.modversionrange=false 禁用此行为。

解析器 

并非所有包都位于同一台服务器上;sbt 默认使用标准 Maven2 仓库。如果您的依赖项不在默认仓库之一中,则需要添加解析器以帮助 Ivy 找到它。

要添加额外的仓库,请使用

resolvers += name at location

使用两个字符串之间的特殊 at

例如

resolvers += "Sonatype OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots"

resolvers 密钥在 Keys 中定义如下

val resolvers = settingKey[Seq[Resolver]]("The user-defined additional resolvers for automatically managed dependencies.")

at 方法从两个字符串创建 Resolver 对象。

如果您将其添加为仓库,则 sbt 可以搜索您的本地 Maven 仓库

resolvers += "Local Maven Repository" at "file://"+Path.userHome.absolutePath+"/.m2/repository"

或者,为了方便起见

resolvers += Resolver.mavenLocal

有关定义其他类型仓库的详细信息,请参阅解析器

覆盖默认解析器 

resolvers 不包含默认解析器;它只包含构建定义添加的额外解析器。

sbt 将 resolvers 与一些默认仓库组合起来,形成 externalResolvers

因此,要更改或删除默认解析器,您需要覆盖 externalResolvers 而不是 resolvers

每个配置的依赖项 

通常,依赖项由您的测试代码(在 src/test/scala 中,由 Test 配置编译)而不是您的主代码使用。

如果您希望依赖项仅显示在 Test 配置的类路径中,而不是 Compile 配置的类路径中,请添加 % "test",如下所示

libraryDependencies += "org.apache.derby" % "derby" % "10.4.1.3" % "test"

您也可以使用 Test 配置的类型安全版本,如下所示

libraryDependencies += "org.apache.derby" % "derby" % "10.4.1.3" % Test

现在,如果您在 sbt 交互式提示符中键入 show Compile/dependencyClasspath,您应该看不到 derby jar 文件。但是,如果您键入 show Test/dependencyClasspath,您应该在列表中看到 derby jar 文件。

通常,与测试相关的依赖项,例如 ScalaCheckSpecs2ScalaTest 将使用 % "test" 定义。

有关库依赖项的更多详细信息和技巧,请参阅本页