Scala 的插件繼承自 Java 插件并添加了對 Scala 項目的支持。它可以處理 Scala 代碼,以及混合的 Scala 和 Java 代碼,甚至是純 Java 代碼(盡管我們不一定推薦使用)。該插件支持聯(lián)合編譯,聯(lián)合編譯可以通過 Scala 及 Java 的各自的依賴任意地混合及匹配它們的代碼。例如,一個 Scala 類可以繼承自一個 Java 類,而這個 Java 類也可以繼承自一個 Scala 類。這樣一來,我們就能夠在項目中使用最適合的語言,并且在有需要的情況下用其他的語言重寫其中的任何類。
要使用 Scala 插件,請在構建腳本中包含以下語句:
使用 Scala 插件
build.gradle
apply plugin: 'scala'
Scala 的插件向 project 中添加了以下任務。
表 25.1. Scala 插件 - 任務
任務名稱 | 依賴于 | 類型 | 描述 |
compileScala
|
compileJava
|
ScalaCompile | 編譯production 的 Scala 源文件。 |
compileTestScala
|
compileTestJava
|
ScalaCompile | 編譯test 的 Scala 的源文件。 |
SourceSet Scala |
SourceSet Java |
ScalaCompile | 編譯給定的source set 里的 Scala 源文件。 |
scaladoc
|
- | scaladoc | 為production 里的 Scala 源文件生成 API 文檔。 |
Scala 插件向 Java 插件所加入的 tasks 添加了以下的依賴。
表 24.2. Scala 感覺 插件 - 額外的 task 依賴
任務名稱 | 依賴于 |
classes
|
compileScala
|
testClasses
|
compileTestScala
|
sourceSet Classes |
SourceSet Scala |
圖 25.1. Scala 插件-任務
Scala 插件會假定如下所示的項目布局。所有 Scala 的源目錄都可以包含 Scala和Java 代碼。Java 源目錄只能包含 Java 源代碼。這些目錄不一定是存在的,或是里面包含有什么內(nèi)容;Scala 插件只會進行編譯,而不管它發(fā)現(xiàn)什么。
表 25.3. Scala 插件 - 項目布局
目錄 | 意義 |
src/main/java
|
產(chǎn)品的Java源代碼 |
src/main/resources
|
產(chǎn)品的資源 |
src/main/scala
|
Production Scala 源代碼。此外可能包含聯(lián)合編譯的 Java 源代碼。 |
src/test/java
|
Java 測試源代碼 |
src/test/resources
|
測試資源 |
src/test/scala
|
Test Scala 源代碼。此外可能包含聯(lián)合編譯的 Java 源代碼。 |
sourceSet /java |
給定的源集的Java源代碼 |
sourceSet /resources |
給定的源集的資源 |
sourceSet /scala |
給定的source set 的 Scala 源代碼。此外可能包含聯(lián)合編譯的 Java 源代碼。 |
和 Java 插件一樣,Scala 插件允許把 Scala 的 production 和 test 的源文件配置為自定義的位置。
自定義 Scala 源文件布局
build.gradle
sourceSets {
main {
scala
srcDirs = ['src/scala']
}
}
test {
scala
srcDirs = ['test/scala']
}
}
}
Scala 項目需要聲明一個 scala-library 依賴項。這個依賴會在編譯和運行的類路徑時用到。它還將用于分別獲取 Scala 編譯器及 Scaladoc 工具。
如果 Scala 用于 production 代碼, scala-library 依賴應該添加到 compile 的配置中:
為production 代碼定義一個Scala 依賴
build.gradle
repositories {
mavenCentral()
}
dependencies {
compile 'org.scala-lang:scala-library:2.9.1'
}
如果 Scala 僅用于測試代碼, scala-library 依賴應被添加到 testCompile 配置中:
為 test 代碼定義一個Scala 依賴
build.gradle
dependencies {
testCompile "org.scala-lang:scala-library:2.9.2"
}
ScalaCompile 和 ScalaDoc tasks 會以兩種方式使用 Scala: 在它們的 classpath 以及scalaClasspath 上。前者用于在源代碼中查找類的引用,通常會包含 scala-library 和其他庫。后者用來分別加載和執(zhí)行 Scala 編譯器和 Scala 工具,并且應該只包含 scala-library及其依賴項。
除非顯式配置了一個 task 的 scalaClasspath ,否則 Scala(基礎)插件會嘗試推斷該 task 的 classpath。以如下方式進行:
Scala 插件沒有向 project 添加任何的公約屬性。
Scala 的插件向 project 的每一個 source set 添加了下列的公約屬性。你可以在你的構建腳本中,把這些屬性當成是 source set 對象中的屬性一樣使用。
表 25.4. Scala 插件 - source set 屬性
屬性名稱 | 類型 | 默認值 | 描述 |
scala
|
SourceDirectorySet (read-only) | 非空 | 該source set 中的 Scala 源文件。包含在 Scala 源目錄中找到的所有的.java 文件,并排除所有其他類型的文件。 |
scala.srcDirs
|
Set<File> . |
name /scala] |
源目錄包含該 source set 中的 Scala 源文件。此外可能還包含用于聯(lián)合編譯的 Java 源文件。 |
allScala
|
FileTree (read-only) | 非空 | 該source set 中的所有 Scala 源文件。包含在 Scala 源目錄中找到的所有的.scala 文件。 |
這些屬性由一個 ScalaSourceSet 的約定對象提供。
Scala 的插件還修改了一些 source set 的屬性:
表 25.5. Scala 插件 - source set 屬性
屬性名稱 | 修改的內(nèi)容 |
allJava
|
添加在 Scala 源目錄中找到的所有.java 文件。 |
allSource
|
添加在 Scala 的源目錄中找到的所有源文件。 |
Scala 插件包含了對 fsc,即 Fast Scala Compiler 的支持。fsc 運行在一個單獨的進程中,并且可以顯著地提高編譯速度。
啟用 Fast Scala Compiler
build.gradle
compileScala
scalaCompileOptions.useCompileDaemon = true
// optionally specify host and port of the daemon:
scalaCompileOptions.daemonServer = "localhost:4243"
}
注意,每當 fsc 的編譯類路徑的內(nèi)容發(fā)生變化時,它都需要重新啟動。(它本身不會去檢測編譯類路徑的更改。)這使得它不太適合于多項目的構建。
當 scalaCompileOptions.fork 設置為 true 時,編譯會在外部進程中進行。fork 的詳細情況依賴于所使用的編譯器?;?Ant 的編譯器 (scalaCompileOptions.useAnt = true) 將為每個 ScalaCompile 任務 fork 一個新進程,而默認情況下它不進行 fork。基于 Zinc 的編譯器 (scalaCompileOptions.useAnt = false) 將利用 Gradle 編譯器守護進程,且默認情況下也是這樣。
外部過程默認使用JVM 的的默認內(nèi)存設置。如果要調(diào)整內(nèi)存設置,請根據(jù)需要配置scalaCompileOptions.forkOptions :
調(diào)整內(nèi)存設置
build.gradle
tasks.withType(ScalaCompile) {
configure(scalaCompileOptions.forkOptions) {
memoryMaximumSize = '1g'
jvmArgs = ['-XX:MaxPermSize=512m']
}
}
增量編譯是只編譯那些源代碼在上一次編譯之后有修改的類,及那些受這些修改影響到的類,它可以大大減少 Scala 的編譯時間。頻繁編譯代碼的增量部分是非常有用的,因為在開發(fā)時我們經(jīng)常要這樣做。
Scala 插件現(xiàn)在通過集成 Zinc 來支持增量編譯, 它是 sbt 增量 Scala 編譯器的一個單機版本。若要把 ScalaCompile 任務從默認的基于 Ant 的編譯器切換為新的基于 Zinc 的編譯器,需要將 scalaCompileOptions.useAnt 設置為 false:
激活基于 Zinc 編譯器
build.gradlev
tasks.withType(ScalaCompile) {
scalaCompileOptions.useAnt = false
}
除非在 API 文檔中另有說明,否則基于 Zinc 的據(jù)編譯器支持與基于 Ant 的編譯器完全相同的配置選項。但是,要注意的是,Zinc 編譯器需要 Java 6 或其以上版本來運行。這意味著 Gradle 本身要使用 Java 6 或其以上版本。
Scala 插件添加了一個名為 zinc 的配置,以解析 Zinc 庫及其依賴。如果要重寫 Gradle 默認情況下使用的 Zinc 版本,請?zhí)砑右粋€顯式的 Zinc 依賴項 (例如zinc "com.typesafe.zinc:zinc:0.1.4")。無論使用哪一個 Zinc 版本,Zinc 都是使用在scalaTools配置上找到的 Scala 編譯器。
就像 Gradle 上基于Ant 的編譯器一樣,基于 Zinc 的編譯器支持 Java 和 Scala 代碼的聯(lián)合編譯。默認情況下,在 src/main/scala 下的所有 Java 和 Scala 代碼都會進行聯(lián)合編譯。使用基于 Zinc 的編譯器時,即使是 Java 代碼也將會進行增量編譯。
增量編譯需要源代碼的相關性分析。解析結果進入由 scalaCompileOptions.incrementalOptions.analysisFile 所指定的文件(它有一個合理的默認值)。在多項目構建中,分析文件被傳遞給下游的 ScalaCompile 任務,以啟用跨項目的增量編譯。對于由 Scala 插件添加的 ScalaCompile 任務,無需對這一點進行配置。對于其他的 ScalaCompile 任務,需要根據(jù)類文件夾或 Jar archive 的代碼中,是哪一個的代碼被傳遞給 ScalaCompile 任務的下游類路徑,把ScalaCompileOptions.incrementalOptions.publishedCode 配置為指向它們。注意,如果publishedCode 設置不正確,上游代碼發(fā)生變化時下游任務可能不會重新編譯代碼,導致編譯結果不正確。
由于依賴分析的系統(tǒng)開銷,一次干凈的編譯或在代碼有了較大的更改之后的編譯,可能花費的時間要長于使用基于 Ant 的編譯器。對于 CI 構建和版本的構建中,我們目前推薦使用基于 Ant 的編譯器。
注意現(xiàn)在 Zinc 基于守護進程模式的 Nailgun 還不支持。相反,我們打算加強 Gradle 自己的編譯器守護進程,使得在跨 Gradle 調(diào)用時繼續(xù)存活,利用同一個 Scala 編譯器。這將會為 Scala 編譯帶來另一個方面上的明顯加速。
當 Eclipse 插件遇到 Scala 項目時,它將添加額外的配置,使得項目能夠在使用 Scala IDE 時開箱即用。具體而言,該插件添加一個 Scala 性質(zhì)和依賴的容器。
當 IDEA 插件遇到 Scala 項目時,它將添加額外的配置,使得項目能夠在使用 IDEA 時開箱即用。具體而言,該插件添加了一個 Scala facet 和一個匹配項目的類路徑上的 Scala 版本的 Scala 編譯器類庫。
更多建議: