Scala 插件
Scala 插件擴展了 Java 插件,以添加對 Scala 專案的支援。此插件還支援聯合編譯,這允許您在 Scala 和 Java 程式碼之間自由混合和匹配,並在兩個方向上都有依賴關係。例如,Scala 類別可以擴展 Java 類別,而 Java 類別又可以擴展 Scala 類別。這使得可以使用最適合工作的語言,並在需要時以另一種語言重寫任何類別。
請注意,如果您想從 API / 實作分離 中受益,您也可以將 java-library
插件應用於您的 Scala 專案。
用法
若要使用 Scala 插件,請在您的建置腳本中包含以下內容
plugins {
id("scala")
}
plugins {
id("scala")
}
任務
Scala 插件將以下任務添加到專案中。有關更改 Java 編譯任務的依賴關係的資訊,請參閱此處。
compileScala
— ScalaCompile-
依賴於:
compileJava
編譯生產 Scala 源碼檔案。
compileTestScala
— ScalaCompile-
依賴於:
compileTestJava
編譯測試 Scala 源碼檔案。
compileSourceSetScala
— ScalaCompile-
依賴於:
compileSourceSetJava
編譯給定 source set 的 Scala 源碼檔案。
scaladoc
— ScalaDoc-
為生產 Scala 源碼檔案產生 API 文件。
ScalaCompile
和 ScalaDoc
任務支援開箱即用的 Java 工具鏈。
Scala 插件將以下依賴關係添加到 Java 插件添加的任務中。
任務名稱 | 依賴於 |
---|---|
|
|
|
|
|
|

專案佈局
Scala 插件假設使用如下所示的專案佈局。所有 Scala 源碼目錄都可以包含 Scala 和 Java 程式碼。Java 源碼目錄可能僅包含 Java 原始碼。這些目錄都不需要存在或包含任何內容;Scala 插件只會編譯它找到的任何內容。
src/main/java
-
生產 Java 源碼。
src/main/resources
-
生產資源,例如 XML 和屬性檔。
src/main/scala
-
生產 Scala 源碼。也可能包含用於聯合編譯的 Java 源碼檔案。
src/test/java
-
測試 Java 源碼。
src/test/resources
-
測試資源。
src/test/scala
-
測試 Scala 源碼。也可能包含用於聯合編譯的 Java 源碼檔案。
src/sourceSet/java
-
source set 名稱為 sourceSet 的 Java 源碼。
src/sourceSet/resources
-
source set 名稱為 sourceSet 的資源。
src/sourceSet/scala
-
給定 source set 的 Scala 源碼檔案。也可能包含用於聯合編譯的 Java 源碼檔案。
變更專案佈局
就像 Java 插件一樣,Scala 插件允許您為 Scala 生產和測試源碼檔案配置自訂位置。
sourceSets {
main {
scala {
setSrcDirs(listOf("src/scala"))
}
}
test {
scala {
setSrcDirs(listOf("test/scala"))
}
}
}
sourceSets {
main {
scala {
srcDirs = ['src/scala']
}
}
test {
scala {
srcDirs = ['test/scala']
}
}
}
Scala 版本
Scala 版本可以直接在 scala
擴展上宣告。依賴關係會根據宣告的 Scala 版本自動添加到 scalaToolchain
配置中。scalaToolchainRuntimeClasspath
配置解析在 scalaToolchain
配置上宣告的依賴關係,並包含執行 Scala 編譯器所需的文件。
當設定 scalaVersion 屬性時,不需要宣告 Scala SDK 的直接依賴關係。 |
repositories {
mavenCentral()
}
scala {
scalaVersion = "2.13.12"
}
repositories {
mavenCentral()
}
scala {
scalaVersion = "2.13.12"
}
配置 Gradle 以使用 Scala 3 與 Scala 2 沒有區別。
repositories {
mavenCentral()
}
scala {
scalaVersion = "3.6.3"
}
repositories {
mavenCentral()
}
scala {
scalaVersion = "3.6.3"
}
scalaVersion 屬性正在孵化中。 |
宣告 Scala 依賴關係
當不使用 scalaVersion
屬性時,必須在 implementation
配置上手動宣告 Scala SDK 依賴關係。不建議使用此模式,因為它依賴於從生產執行期 classpath 推斷 Scala classpath。從 scala
擴展中省略 Scala 版本將在未來的 Gradle 版本中棄用。
Scala 2 專案需要宣告 scala-library
依賴關係。
repositories {
mavenCentral()
}
dependencies {
implementation("org.scala-lang:scala-library:2.13.12")
}
repositories {
mavenCentral()
}
dependencies {
implementation("org.scala-lang:scala-library:2.13.12")
}
Scala 3 專案需要宣告 scala3-library_3
依賴關係,而不是
repositories {
mavenCentral()
}
dependencies {
implementation("org.scala-lang:scala3-library_3:3.6.3")
}
repositories {
mavenCentral()
}
dependencies {
implementation("org.scala-lang:scala3-library_3:3.6.3")
}
如果 Scala 僅用於測試程式碼,則應將 scala-library
依賴關係添加到 testImplementation
配置中
dependencies {
testImplementation("org.scala-lang:scala-library:2.13.12")
}
dependencies {
testImplementation("org.scala-lang:scala-library:2.13.12")
}
自動配置 scalaClasspath
ScalaCompile
和 ScalaDoc
任務以兩種方式使用 Scala 程式碼:在其 classpath
上,以及在其 scalaClasspath
上。前者用於定位源碼引用的類別,並且通常將包含 scala-library
以及其他函式庫。後者用於載入和執行 Scala 編譯器和 Scaladoc 工具(分別),並且應僅包含 scala-compiler
函式庫及其依賴關係。
如果未設定 scala
擴展的 scalaVersion
屬性,並且未明確配置任務的 scalaClasspath
,則 Scala (基礎) 插件將嘗試從任務的 classpath
推斷 classpath。這是透過以下方式完成的
-
如果在
classpath
上找到scala-library
jar 檔,並且專案至少宣告了一個倉庫,則對應的scala-compiler
倉庫依賴關係將被添加到scalaClasspath
。 -
否則,任務的執行將會失敗,並顯示一條訊息,指出無法推斷
scalaClasspath
。
配置 Zinc 編譯器
Scala 插件使用名為 zinc
的配置來解析 Zinc 編譯器及其依賴關係。Gradle 將提供 Zinc 的預設版本,但是如果您需要使用特定的 Zinc 版本,則可以更改它。Gradle 支援 1.6.0 及更高版本的 Zinc。
scala {
scalaVersion = "2.13.12"
zincVersion = "1.10.4"
}
scala {
scalaVersion = "2.13.12"
zincVersion = "1.10.4"
}
Zinc 編譯器本身需要相容版本的 scala-library
,這可能與您的應用程式要求的版本不同。Gradle 會負責為您指定相容版本的 scala-library
。
您可以透過為 zinc
配置執行 dependencyInsight 來診斷所選 Zinc 編譯器版本的相關問題。
Gradle 版本 | 支援的 Zinc 版本 | Zinc 座標 | 要求的 Scala 版本 | 支援的 Scala 編譯版本 |
---|---|---|---|---|
7.5 及更新版本 |
SBT Zinc。版本 1.6.0 及更高版本。 |
|
執行 Zinc 需要 Scala |
可以編譯 Scala |
6.0 到 7.5 |
SBT Zinc。版本 1.2.0 及更高版本。 |
|
執行 Zinc 需要 Scala |
可以編譯 Scala |
1.x 到 5.x |
已棄用 Typesafe Zinc 編譯器。 版本 0.3.0 及更高版本,除了 0.3.2 到 0.3.5.2 之外。 |
|
執行 Zinc 需要 Scala |
可以編譯 Scala |
為 Scala 編譯器添加插件
Scala 插件添加了一個名為 scalaCompilerPlugins
的配置,該配置用於宣告和解析可選編譯器插件。
dependencies {
scalaCompilerPlugins("org.typelevel:kind-projector_2.13.12:0.13.2")
}
dependencies {
scalaCompilerPlugins("org.typelevel:kind-projector_2.13.12:0.13.2")
}
慣例屬性
Scala 插件未向專案添加任何慣例屬性。
Source set 屬性
Scala 插件將以下擴展添加到專案中的每個 source set。您可以在建置腳本中使用它們,就像它們是 source set 物件的屬性一樣。
scala
— SourceDirectorySet (唯讀)-
此 source set 的 Scala 源碼檔案。包含在 Scala 源碼目錄中找到的所有
.scala
和.java
檔案,並排除所有其他類型的檔案。預設值: 非 null。 scala.srcDirs
—Set<File>
-
包含此 source set 的 Scala 源碼檔案的源碼目錄。也可能包含用於聯合編譯的 Java 源碼檔案。可以使用理解隱式轉換為檔案集合中描述的任何內容進行設定。預設值:
[projectDir/src/name/scala]
。 allScala
— FileTree (唯讀)-
此 source set 的所有 Scala 源碼檔案。僅包含在 Scala 源碼目錄中找到的
.scala
檔案。預設值: 非 null。
這些擴展由 ScalaSourceSet 類型的物件支援。
Scala 插件還修改了一些 source set 屬性
屬性名稱 | 變更 |
---|---|
|
添加在 Scala 源碼目錄中找到的所有 |
|
添加在 Scala 源碼目錄中找到的所有源碼檔案。 |
目標位元組碼等級與 Java API 版本
執行 Scala 編譯任務時,Gradle 將始終添加一個參數來配置 Scala 編譯器的 Java 目標,該目標衍生自 Gradle 配置
-
當使用工具鏈時,會選擇
-release
選項(或較舊 Scala 版本的target
),其版本與已配置工具鏈的 Java 語言等級相符。 -
當不使用工具鏈時,Gradle 將始終傳遞
target
標誌 — 確切值取決於 Scala 版本 — 以編譯為 Java 8 位元組碼。
這表示將工具鏈與最新的 Java 版本和舊的 Scala 版本一起使用可能會導致失敗,因為 Scala 在一段時間內僅支援 Java 8 位元組碼。然後解決方案是在工具鏈中使用正確的 Java 版本,或在需要時顯式降級目標。 |
下表說明了 Gradle 計算的值
Scala 版本 | 使用中的工具鏈 | 參數值 |
---|---|---|
版本 < |
是 |
|
否 |
|
|
|
是 |
|
否 |
|
|
|
是 |
|
否 |
|
|
|
是 |
|
否 |
|
在 ScalaCompile.scalaCompileOptions.additionalParameters
上顯式設定任何這些標誌,或使用包含 java-output-version
的標誌,都會禁用該邏輯,而改用顯式標誌。
在外部程序中編譯
Scala 編譯在外部程序中進行。
外部程序的記憶體設定預設為 JVM 的預設值。若要調整記憶體設定,請根據需要配置 scalaCompileOptions.forkOptions
屬性
tasks.withType<ScalaCompile>().configureEach {
scalaCompileOptions.forkOptions.apply {
memoryMaximumSize = "1g"
jvmArgs = listOf("-XX:MaxMetaspaceSize=512m")
}
}
tasks.withType(ScalaCompile) {
scalaCompileOptions.forkOptions.with {
memoryMaximumSize = '1g'
jvmArgs = ['-XX:MaxMetaspaceSize=512m']
}
}
增量編譯
透過僅編譯自上次編譯以來原始碼已變更的類別,以及受這些變更影響的類別,增量編譯可以顯著減少 Scala 編譯時間。當頻繁編譯小的程式碼增量時,它尤其有效,這在開發時經常發生。
tasks.withType<ScalaCompile>().configureEach {
scalaCompileOptions.apply {
isForce = true
}
}
tasks.withType(ScalaCompile) {
scalaCompileOptions.with {
force = true
}
}
注意: 僅當至少一個輸入源碼檔案已變更時,這才會導致重新編譯所有類別。如果源碼檔案沒有變更,則 compileScala
任務仍將照常被視為 UP-TO-DATE
。
基於 Zinc 的 Scala 編譯器支援 Java 和 Scala 程式碼的聯合編譯。預設情況下,src/main/scala
下的所有 Java 和 Scala 程式碼都將參與聯合編譯。即使 Java 程式碼也將被增量編譯。
增量編譯需要對源碼進行依賴關係分析。此分析的結果儲存在由 scalaCompileOptions.incrementalOptions.analysisFile
指定的檔案中(該檔案具有合理的預設值)。在多專案建置中,分析檔案會傳遞到下游 ScalaCompile
任務,以啟用跨專案邊界的增量編譯。對於 Scala 插件添加的 ScalaCompile
任務,無需進行任何配置即可使其工作。對於您可能添加的其他 ScalaCompile
任務,需要配置屬性 scalaCompileOptions.incrementalOptions.publishedCode
,以指向類別資料夾或 Jar 封存檔,程式碼透過該資料夾或 Jar 封存檔傳遞到下游 ScalaCompile
任務的編譯類別路徑。請注意,如果未正確設定 publishedCode
,則下游任務可能不會重新編譯受上游變更影響的程式碼,從而導致不正確的編譯結果。
請注意,不支援基於 Zinc Nailgun 的常駐程式模式。相反,我們計劃增強 Gradle 自己的編譯器常駐程式,使其在 Gradle 調用之間保持活動狀態,從而重複使用相同的 Scala 編譯器。預計這將為 Scala 編譯帶來另一個顯著的速度提升。
Eclipse 整合
當 Eclipse 插件遇到 Scala 專案時,它會添加額外的配置,使專案可以開箱即用地與 Scala IDE 一起使用。具體來說,該插件添加了 Scala 特性和依賴容器。
IntelliJ IDEA 整合
當 IDEA 插件遇到 Scala 專案時,它會添加額外的配置,使專案可以開箱即用地與 IDEA 一起使用。具體來說,該插件添加了 Scala SDK (IntelliJ IDEA 14+) 和與專案類別路徑上的 Scala 版本相符的 Scala 編譯器函式庫。Scala 插件向後相容於早期版本的 IntelliJ IDEA,並且可以透過在 IdeaModel 上配置 targetVersion
來添加 Scala facet 而不是預設 Scala SDK。
idea {
targetVersion = "13"
}
idea {
targetVersion = '13'
}