Scala 插件
Scala 插件扩展了Java 插件以添加对Scala项目的支持。该插件还支持联合编译,允许您自由地混合和匹配 Scala 和 Java 代码,并具有双向依赖关系。例如,Scala 类可以扩展 Java 类,而 Java 类又扩展 Scala 类。这使得可以使用最适合工作的语言,并在需要时用其他语言重写任何类。
请注意,如果您想从API/实现分离中受益,您还可以将该java-library
插件应用到您的 Scala 项目中。
用法
要使用 Scala 插件,请在构建脚本中包含以下内容:
plugins {
scala
}
plugins {
id 'scala'
}
任务
项目布局
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
-
名为sourceSet的源集的 Java 源。
src/sourceSet/resources
-
名为sourceSet的源集的资源。
src/sourceSet/scala
-
给定源集的 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-library
依赖项。然后,此依赖项将用于编译和运行时类路径。它还将分别用于获取 Scala 编译器和 Scaladoc 工具。[ 1 ]
如果 Scala 用于生产代码,scala-library
则应将依赖项添加到implementation
配置中:
repositories {
mavenCentral()
}
dependencies {
implementation("org.scala-lang:scala-library:2.13.12")
testImplementation("junit:junit:4.13")
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.scala-lang:scala-library:2.13.12'
testImplementation 'junit:junit:4.13'
}
如果您想使用 Scala 3 而不是依赖scala-library
项,您应该添加scala3-library_3
依赖项:
plugins {
scala
}
repositories {
mavenCentral()
}
dependencies {
implementation("org.scala-lang:scala3-library_3:3.0.1")
testImplementation("org.scalatest:scalatest_3:3.2.9")
testImplementation("junit:junit:4.13")
}
dependencies {
implementation("commons-collections:commons-collections:3.2.2")
}
plugins {
id 'scala'
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.scala-lang:scala3-library_3:3.0.1'
implementation 'commons-collections:commons-collections:3.2.2'
testImplementation 'org.scalatest:scalatest_3:3.2.9'
testImplementation 'junit:junit:4.13'
}
如果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
库及其依赖项。
除非显式配置任务scalaClasspath
,否则 Scala(基本)插件将尝试从任务的classpath
.这是按如下方式完成的:
-
如果
scala-library
在 上找到一个 jarclasspath
,并且该项目至少声明了一个存储库,scala-compiler
则会将相应的存储库依赖项添加到 中scalaClasspath
。 -
否则,任务执行将失败,并显示一条消息,指出
scalaClasspath
无法推断。
配置 Zinc 编译器
Scala 插件使用名为 的配置zinc
来解析Zinc 编译器及其依赖项。 Gradle 将提供默认版本的 Zinc,但如果您需要使用特定的 Zinc 版本,则可以更改它。 Gradle 支持 Zinc 1.6.0 及以上版本。
scala {
zincVersion = "1.9.3"
}
scala {
zincVersion = "1.9.3"
}
Zinc 编译器本身需要一个兼容版本,scala-library
该版本可能与您的应用程序所需的版本不同。 Gradle 负责scala-library
为您指定兼容版本。
您可以通过运行dependencyInsight进行配置来诊断所选 Zinc 编译器版本的问题zinc
。
摇篮版本 | 支持的锌版本 | 锌坐标 | 所需的 Scala 版本 | 支持的Scala编译版本 |
---|---|---|---|---|
7.5 及更高版本 |
SBT 锌。 1.6.0 及以上版本。 |
|
运行 |
Scala |
6.0 至 7.5 |
SBT 锌。 1.2.0 及以上版本。 |
|
运行 |
Scala |
1.x 至 5.x |
已弃用Typesafe Zinc 编译器。版本 0.3.0 及更高版本,0.3.2 至 0.3.5.2 除外。 |
|
运行 |
Scala |
向 Scala 编译器添加插件
Scala 插件添加了一个名为 的配置scalaCompilerPlugins
,用于声明和解析可选的编译器插件。
dependencies {
implementation("org.scala-lang:scala-library:2.13.12")
scalaCompilerPlugins("org.typelevel:kind-projector_2.13.12:0.13.2")
}
dependencies {
implementation "org.scala-lang:scala-library:2.13.12"
scalaCompilerPlugins "org.typelevel:kind-projector_2.13.12:0.13.2"
}
约定属性
Scala 插件不会向项目添加任何约定属性。
源集属性
Scala 插件将以下扩展添加到项目中的每个源集。您可以在构建脚本中使用它们,就像它们是源集对象的属性一样。
scala
— SourceDirectorySet(只读)-
该源集的 Scala 源文件。包含在 Scala 源目录中找到的所有文件,并排除所有其他类型的文件
.scala
。默认值:非空。.java
scala.srcDirs
—Set<File>
-
包含此源集的 Scala 源文件的源目录。还可能包含用于联合编译的 Java 源文件。可以使用了解文件集合的隐式转换中描述的任何内容进行设置。 默认值: 。
[projectDir/src/name/scala]
allScala
—文件树(只读)-
该源集的所有 Scala 源文件。仅包含
.scala
Scala 源目录中找到的文件。默认值:非空。
这些扩展由ScalaSourceSet类型的对象支持。
Scala 插件还修改了一些源集属性:
物业名称 | 改变 |
---|---|
|
添加 |
|
添加在 Scala 源目录中找到的所有源文件。 |
目标字节码级别和 Java API 版本
运行 Scala 编译任务时,Gradle 始终会添加一个参数来配置从 Gradle 配置派生的 Scala 编译器的 Java 目标:
-
使用工具链时,选择该
-release
选项,或者target
对于较旧的 Scala 版本,选择与配置的工具链的 Java 语言级别匹配的版本。 -
当不使用工具链时,Gradle 将始终传递一个
target
标志(其确切值取决于 Scala 版本)来编译为 Java 8 字节码。
这意味着使用具有最新 Java 版本和旧 Scala 版本的工具链可能会导致失败,因为 Scala 在一段时间内仅支持 Java 8 字节码。然后,解决方案是在工具链中使用正确的 Java 版本,或者在需要时显式降级目标。 |
下表解释了 Gradle 计算的值:
Scala版本 | 使用中的工具链 | 参数值 |
---|---|---|
版本< |
是的 |
|
不 |
|
|
|
是的 |
|
不 |
|
|
|
是的 |
|
不 |
|
|
|
是的 |
|
不 |
|
显式设置任何这些标志,或使用包含java-output-version
, on 的标志ScalaCompile.scalaCompileOptions.additionalParameters
会禁用该逻辑,转而使用显式标志。
在外部进程中编译
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 编译时间。当频繁编译小代码增量时(开发时经常这样做),它特别有效。
Scala 插件默认通过与Zinc集成进行增量编译,Zinc 是sbt增量 Scala 编译器的独立版本。如果要禁用增量编译,请force = true
在构建文件中设置:
tasks.withType<ScalaCompile>().configureEach {
scalaCompileOptions.apply {
isForce = true
}
}
tasks.withType(ScalaCompile) {
scalaCompileOptions.with {
force = true
}
}
注意:只有当至少一个输入源文件发生更改时,这才会导致所有类重新编译。如果源文件没有更改,compileScala
任务仍将被视为UP-TO-DATE
正常。
基于Zinc的Scala编译器支持Java和Scala代码的联合编译。默认情况下,所有Java和Scala下的代码src/main/scala
都会参与联合编译。甚至Java代码也会被增量编译。
增量编译需要对源代码进行依赖分析。该分析的结果存储在指定的文件中scalaCompileOptions.incrementalOptions.analysisFile
(具有合理的默认值)。在多项目构建中,分析文件将传递到下游ScalaCompile
任务,以实现跨项目边界的增量编译。对于ScalaCompile
Scala 插件添加的任务,无需配置即可完成此操作。对于您可能添加的其他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,并且可以通过在IdeaModeltargetVersion
上进行配置来添加 Scala 方面而不是默认的 Scala SDK 。
idea {
targetVersion = "13"
}
idea {
targetVersion = '13'
}