現在有一個關於函式庫管理的入門頁面,您可能需要先閱讀。
文件維護注意事項:最好移除此頁面與入門頁面之間的重疊之處,讓此頁面保留更進階的主題,例如檢查碼和外部 Ivy 檔案。
您可以使用兩種方式透過 sbt 管理函式庫:手動或自動。這兩種方式也可以混合使用。本頁討論這兩種方法。此處顯示的所有組態都是直接放入 .sbt 檔案中的設定。
手動管理依賴項目涉及將您想要使用的任何 jar 複製到 lib
目錄。sbt 會在編譯、測試、執行和使用直譯器時將這些 jar 放入類別路徑中。您負責新增、移除、更新和以其他方式管理此目錄中的 jar。除非您想要變更儲存 jar 的目錄位置,否則使用此方法不需要修改專案定義。
若要變更儲存 jar 的目錄,請在專案定義中變更 unmanagedBase
設定。例如,若要使用 custom_lib/
unmanagedBase := baseDirectory.value / "custom_lib"
如果您想要更多控制和彈性,請覆寫 unmanagedJars
任務,該任務最終會將手動依賴項目提供給 sbt。預設實作大致如下
Compile / unmanagedJars := (baseDirectory.value ** "*.jar").classpath
如果您想要從多個目錄新增 jar,除了預設目錄之外,您可以執行
Compile / unmanagedJars ++= {
val base = baseDirectory.value
val baseDirectories = (base / "libA") +++ (base / "b" / "lib") +++ (base / "libC")
val customJars = (baseDirectories ** "*.jar") +++ (base / "d" / "my.jar")
customJars.classpath
}
如需建構路徑的詳細資訊,請參閱路徑。
此依賴管理方法涉及指定專案的直接依賴項目,並讓 sbt 處理擷取和更新依賴項目。
sbt 1.3.0+ 使用 Coursier 來實作依賴管理。在 sbt 1.3.0 之前,sbt 已使用 Apache Ivy 十年。Coursier 在保持相容性方面做得很好,但某些功能可能特定於 Apache Ivy。在這些情況下,您可以使用以下設定切換回 Ivy
ThisBuild / useCoursier := false
內嵌宣告是一種指定要自動擷取的依賴項目的基本方式。它們旨在作為使用 Ivy 的完整組態的輕量級替代方案。
宣告依賴項目看起來像
libraryDependencies += groupID % artifactID % revision
或
libraryDependencies += groupID % artifactID % revision % configuration
如需組態對應的詳細資訊,請參閱組態。此外,可以一起宣告數個依賴項目
libraryDependencies ++= Seq(
groupID %% artifactID % revision,
groupID %% otherID % otherRevision
)
如果您正在使用以 sbt 建置的依賴項目,請將第一個 %
加倍為 %%
libraryDependencies += groupID %% artifactID % revision
這將使用以您目前使用的 Scala 版本建置的依賴項目的正確 jar。如果您在解析此類依賴項目時遇到錯誤,則該依賴項目可能未針對您使用的 Scala 版本發佈。如需詳細資訊,請參閱交叉建置。
Ivy 可以根據您指定的條件約束來選取模組的最新修訂版本。您不需要像 "1.6.1"
這樣的固定修訂版本,而是指定 "latest.integration"
、"2.9.+"
或 "[1.0,)"
。如需詳細資訊,請參閱Ivy 修訂版本文件。
sbt 預設使用標準 Maven2 儲存庫。
使用以下形式宣告其他儲存庫
resolvers += name at location
例如
libraryDependencies ++= Seq(
"org.apache.derby" % "derby" % "10.4.1.3",
"org.specs" % "specs" % "1.6.1"
)
resolvers += "Sonatype OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots"
如果您將本機 Maven 儲存庫新增為儲存庫,sbt 可以搜尋您的本機 Maven 儲存庫
resolvers += "Local Maven Repository" at "file://"+Path.userHome.absolutePath+"/.m2/repository"
如需定義其他類型儲存庫的詳細資訊,請參閱解析器。
resolvers
組態其他內嵌使用者解析器。根據預設,sbt
會將這些解析器與預設儲存庫 (Maven Central 和本機 Ivy 儲存庫) 結合,以形成 externalResolvers
。若要對儲存庫進行更多控制,請直接設定 externalResolvers
。若要僅指定除通常預設值以外的儲存庫,請組態 resolvers
。
例如,若要除了預設儲存庫之外還使用 Sonatype OSS 快照儲存庫,
resolvers += "Sonatype OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots"
若要使用本機儲存庫,但不使用 Maven Central 儲存庫
externalResolvers := Resolver.combineDefaultResolvers(resolvers.value.toVector, mavenCentral = false)
用來擷取 sbt、Scala、外掛程式和應用程式依賴項目的儲存庫可以在全域組態中宣告,以覆寫在建置或外掛程式定義中組態的解析器。有兩個部分
可以透過定義 ~/.sbt/repositories
來覆寫啟動器使用的儲存庫,該檔案必須包含格式與 Launcher
組態檔案相同的 [repositories]
區段。例如
[repositories]
local
my-maven-repo: https://example.org/repo
my-ivy-repo: https://example.org/ivy-repo/, [organization]/[module]/[revision]/[type]s/[artifact](-[classifier]).[ext]
可以在 sbt 啟動指令碼中使用 sbt.repository.config
系統屬性來指定儲存庫檔案的不同位置。最後一步是將 sbt.override.build.repos
設定為 true,以將這些儲存庫用於依賴項目解析和擷取。
如果您的專案需要儲存庫中不存在的依賴項目,則可以如下指定其 jar 的直接 URL
libraryDependencies += "slinky" % "slinky" % "2.1" from "https://slinky2.googlecode.com/svn/artifacts/2.1/slinky.jar"
如果無法透過組態的儲存庫找到依賴項目,則僅將 URL 用作後援。此外,明確 URL 不會包含在已發佈的中繼資料中 (即 pom 或 ivy.xml)。
根據預設,這些宣告會以傳遞方式擷取所有專案依賴項目。在某些情況下,您可能會發現專案所列的依賴項目對於建置不是必要的。例如,使用 Felix OSGI 架構的專案僅明確需要其主要 jar 來進行編譯和執行。請避免使用 intransitive()
或 notTransitive()
擷取成品依賴項目,如此範例所示
libraryDependencies += "org.apache.felix" % "org.apache.felix.framework" % "1.8.0" intransitive()
您可以使用 classifier
方法指定依賴項目的分類器。例如,若要取得 TestNG 的 jdk15 版本
libraryDependencies += "org.testng" % "testng" % "5.7" classifier "jdk15"
對於多個分類器,請使用多個 classifier
呼叫
libraryDependencies +=
"org.lwjgl.lwjgl" % "lwjgl-platform" % lwjglVersion classifier "natives-windows" classifier "natives-linux" classifier "natives-osx"
若要以傳遞方式取得所有依賴項目的特定分類器,請執行 updateClassifiers
任務。根據預設,這會解析具有 sources
或 javadoc
分類器的所有成品。透過組態 transitiveClassifiers
設定來選取要取得的分類器。例如,若要僅擷取來源
transitiveClassifiers := Seq("sources")
若要排除依賴項目的某些傳遞依賴項目,請使用 excludeAll
或 exclude
方法。當要為專案發佈 pom 時,應該使用 exclude
方法。它需要排除的組織和模組名稱。例如,
libraryDependencies +=
"log4j" % "log4j" % "1.2.15" exclude("javax.jms", "jms")
excludeAll
方法更具彈性,但因為它無法在 pom.xml 中表示,因此僅應在不需要產生 pom 時使用。例如,
libraryDependencies +=
"log4j" % "log4j" % "1.2.15" excludeAll(
ExclusionRule(organization = "com.sun.jdmk"),
ExclusionRule(organization = "com.sun.jmx"),
ExclusionRule(organization = "javax.jms")
)
如需 API 詳細資訊,請參閱ModuleID。
在某些情況下,應從所有依賴項目中排除傳遞依賴項目。這可以透過在 excludeDependencies
中設定 ExclusionRules
來實現。
excludeDependencies ++= Seq(
// commons-logging is replaced by jcl-over-slf4j
ExclusionRule("commons-logging", "commons-logging")
)
下載來源和 API 文件 jar 通常由 IDE 外掛程式處理。這些外掛程式會使用 updateClassifiers
和 updateSbtClassifiers
任務,這些任務會產生參考這些 jar 的 Update-Report
。
若要讓 sbt 在不使用 IDE 外掛程式的情況下下載依賴項目的來源,請將 withSources()
新增至依賴項目定義。對於 API jar,請新增 withJavadoc()
。例如
libraryDependencies +=
"org.apache.felix" % "org.apache.felix.framework" % "1.8.0" withSources() withJavadoc()
請注意,這不是傳遞的。請使用 update*Classifiers
任務。
可以透過將鍵/值對傳遞給 extra
方法來指定額外屬性。
依據額外屬性選擇依賴
libraryDependencies += "org" % "name" % "rev" extra("color" -> "blue")
在目前的專案上定義額外屬性
projectID := {
val previous = projectID.value
previous.extra("color" -> "blue", "component" -> "compiler-interface")
}
sbt 還額外支援直接內嵌指定 Ivy 設定檔的 configurations 或 dependencies 區段。您可以將其與內嵌 Scala 依賴和儲存庫宣告混合使用。
例如
ivyXML :=
<dependencies>
<dependency org="javax.mail" name="mail" rev="1.4.2">
<exclude module="activation"/>
</dependency>
</dependencies>
預設情況下,sbt 使用標準 Ivy 主目錄位置 ${user.home}/.ivy2/
。可以透過在 sbt 啟動腳本中設定系統屬性 sbt.ivy.home
,來針對機器範圍進行設定,供 sbt 啟動器和專案使用(請參閱設定)。
例如
java -Dsbt.ivy.home=/tmp/.ivy2/ ...
sbt (透過Ivy) 預設會驗證下載檔案的校驗碼。它也預設會發布 Artifact 的校驗碼。要使用的校驗碼由 checksums 設定指定。
在更新期間停用校驗碼檢查
update / checksums := Nil
在發布 Artifact 期間停用校驗碼建立
publishLocal / checksums := Nil
publish / checksums := Nil
預設值為
checksums := Seq("sha1", "md5")
當依賴解析引入相同程式庫的不同版本時,衝突管理器會決定該怎麼做。預設情況下,會選擇最新的修訂版本。可以透過設定 conflictManager
來變更此行為,其類型為 ConflictManager。請參閱Ivy 文件,以了解不同衝突管理器的詳細資訊。例如,要指定不允許任何衝突,
conflictManager := ConflictManager.strict
設定此選項後,任何衝突都會產生錯誤。要解決衝突,您必須設定依賴覆寫,這將在後面的章節中說明。
以下直接依賴會在 akka-actor 版本上引入衝突,因為 banana-rdf 需要 akka-actor 2.1.4。
libraryDependencies ++= Seq(
"org.w3" %% "banana-rdf" % "0.4",
"com.typesafe.akka" %% "akka-actor" % "2.3.7",
)
預設的衝突管理器將會選擇較新版本的 akka-actor,即 2.3.7。這可以在 show update
的輸出中確認,其中顯示已選擇較新版本,並且較舊版本已被驅逐。
> show update
[info] compile:
[info] com.typesafe.akka:akka-actor_2.10
[info] - 2.3.7
...
[info] - 2.1.4
...
[info] evicted: true
[info] evictedReason: latest-revision
...
[info] callers: org.w3:banana-rdf_2.10:0.4
此外,由於第二個區段已向上調整,因此無法保證 akka-actor 2.1.4 和 2.3.7 的二進位版本相容性。sbt 0.13.6+ 會自動偵測到這一點,並列印以下警告
[warn] There may be incompatibilities among your library dependencies.
[warn] Here are some of the libraries that were evicted:
[warn] * com.typesafe.akka:akka-actor_2.10:2.1.4 -> 2.3.7
[warn] Run 'evicted' to see detailed eviction warnings
由於 akka-actor 2.1.4 和 2.3.7 不具二進位相容性,因此解決此問題的唯一方法是將您的依賴項降級到 akka-actor 2.1.4,或升級 banana-rdf 以使用 akka-actor 2.3。
對於二進位相容衝突,sbt 提供依賴覆寫。它們是使用 dependencyOverrides
設定進行配置的,該設定是一組 ModuleIDs
。例如,以下依賴定義會發生衝突,因為 spark 使用 log4j 1.2.16,而 scalaxb 使用 log4j 1.2.17
libraryDependencies ++= Seq(
"org.spark-project" %% "spark-core" % "0.5.1",
"org.scalaxb" %% "scalaxb" % "1.0.0"
)
預設衝突管理器會選擇 log4j 的最新修訂版本,即 1.2.17
> show update
[info] compile:
[info] log4j:log4j:1.2.17: ...
...
[info] (EVICTED) log4j:log4j:1.2.16
...
要變更選取的版本,請新增覆寫
dependencyOverrides += "log4j" % "log4j" % "1.2.16"
這不會新增對 log4j 的直接依賴,而是會強制修訂版本為 1.2.16。這可以透過 show update
的輸出確認
> show update
[info] compile:
[info] log4j:log4j:1.2.16
...
注意:這是一個僅限 Ivy 的功能,不會包含在發布的 pom.xml 中。
將以下依賴項新增至您的專案將會導致 vpp 2.2.1 的未解析依賴錯誤
libraryDependencies += "org.apache.cayenne.plugins" % "maven-cayenne-plugin" % "3.0.2"
當 sbt 0.13.6+ 無法解析受管理的依賴項時,它會嘗試重建依賴樹狀結構。這是一個近似值,但應該可以幫助您找出問題依賴項的來源。如果可能,sbt 會在模組旁邊顯示來源位置
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: UNRESOLVED DEPENDENCIES ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: foundrylogic.vpp#vpp;2.2.1: not found
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn]
[warn] Note: Unresolved dependencies path:
[warn] foundrylogic.vpp:vpp:2.2.1
[warn] +- org.apache.cayenne:cayenne-tools:3.0.2
[warn] +- org.apache.cayenne.plugins:maven-cayenne-plugin:3.0.2 (/foo/some-test/build.sbt#L28)
[warn] +- d:d_2.10:0.1-SNAPSHOT
請參閱快取解析,以了解效能改進選項。
請參閱發布,以了解如何發布您的專案。
當您需要自訂依賴群組(例如用於外掛程式)時,Ivy 設定是您建置中的實用功能。Ivy 設定本質上是依賴項的具名集合。您可以閱讀Ivy 文件,以了解詳細資訊。
sbt 中內建的設定使用方式與 Maven 中的 scopes 類似。sbt 會根據定義它們的設定,將依賴項新增至不同的類別路徑。請參閱Maven Scopes 的說明,以了解詳細資訊。
您可以透過選取其一個或多個設定,以對應至您的專案的一個或多個設定,來將依賴項放入設定中。最常見的情況是讓您的某個設定 A
使用依賴項的設定 B
。此對應看起來像 "A->B"
。若要將此對應套用至依賴項,請將其新增至您的依賴項定義的結尾
libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.17" % "test->compile"
這表示您專案的 "test"
設定使用 ScalaTest
的 "compile"
設定。請參閱Ivy 文件,以了解更進階的對應。發布到 Maven 儲存庫的大多數專案都會使用 "compile"
設定。
設定的一個實用應用是將不在一般類別路徑上使用的依賴項分組。例如,您的專案可能會使用 "js"
設定來自動下載 jQuery,然後透過修改 resources
將其包含在您的 jar 中。例如
val JS = config("js") hide
ivyConfigurations += JS
libraryDependencies += "jquery" % "jquery" % "3.2.1" % "js->default" from "https://code.jquery.com/jquery-3.2.1.min.js"
Compile / resources ++= update.value.select(configurationFilter("js"))
config
方法定義一個名為 "js"
的新設定,並將其設為專案私有的,以便不會用於發布。請參閱更新報告,以了解有關選取受管理 Artifact 的詳細資訊。
沒有對應 (沒有 "->"
) 的設定會對應到 "default"
或 "compile"
。僅當對應到與這些不同的設定時,才需要 ->
。上面的 ScalaTest 依賴項可以縮短為
libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.17" % "test"
注意:強制可能會造成邏輯不一致,因此不再建議使用。
若要表示我們偏好我們指定的版本,而不是來自間接依賴的版本,請使用 force()
libraryDependencies ++= Seq(
"org.spark-project" %% "spark-core" % "0.5.1",
"log4j" % "log4j" % "1.2.14" force()
)
注意:這是一個僅限 Ivy 的功能,無法包含在發布的 pom.xml 中。
Maven 支援取決於 Coursier 或 Ivy 對 Maven POM 的支援。此支援的已知問題
parent
區段中指定 relativePath
會產生錯誤。ivysettings.xml
檔案中指定儲存庫。