Scala 的插件继承自 Java 插件并添加了对 Scala 项目的支持。它可以处理 Scala 代码,以及混合的
Scala 和 Java 代码,甚至是纯 Java 代码(尽管我们不一定推荐使用)。该插件支持
联合编译
,联合编译可以通过 Scala 及 Java 的各自的依赖任意地混合及匹配它们的代码。例如,一个
Scala 类可以继承自一个 Java 类,而这个 Java 类也可以继承自一个 Scala
类。这样一来,我们就能够在项目中使用最适合的语言,并且在有需要的情况下用其他的语言重写其中的任何类。
The Scala plugin extends the Java plugin to add support for Scala projects. It can deal with
Scala code, mixed Scala and Java code, and even pure Java code (although we don't necessarily recommend to use it for the latter).
The plugin supports
joint compilation
, which allows to freely mix and match Scala and Java code,
with dependencies in both directions. For example, a Scala class can extend a Java class that in turn extends a Scala class.
This makes it possible to use the best language for the job, and to rewrite any class in the other language if needed.
要使用 Scala 插件,请在构建脚本中包含以下语句:
To use the Scala plugin, include in your build script:
Scala 的插件向project 中添加了以下任务。
The Scala plugin adds the following tasks to the project.
表 25.1. Scala 插件 - 任务
Table 25.1. Scala plugin - tasks
任务名称 Task name |
依赖于 Depends on |
类型 Type |
描述 Description |
compileScala
|
compileJava
|
ScalaCompile
|
编译production 的 Scala 源文件。 Compiles production Scala source files. |
compileTestScala
|
compileTestJava
|
ScalaCompile
|
编译test 的 Scala 的源文件。 Compiles test Scala source files. |
compile
|
compile
|
ScalaCompile
|
编译给定的source set 里的 Scala 源文件。 Compiles the given source set's Scala source files. |
scaladoc
|
- |
ScalaDoc
|
为production 里的 Scala 源文件生成 API 文档。 Generates API documentation for the production Scala source files. |
Scala 插件向 Java 插件所加入的 tasks 添加了以下的依赖。
The Scala plugin adds the following dependencies to tasks added by the Java plugin.
表 24.2. Scala感觉 插件 - 额外的task 依赖
Table 25.2. Scala plugin - additional task dependencies
任务名称 Task name |
依赖于 Depends on |
classes
|
compileScala
|
testClasses
|
compileTestScala
|
|
compile
|
Scala 插件会假定如下所示的项目布局。所有 Scala 的源目录都可以包含
Scala<s1><e2>和</e2></s1>Java 代码。Java 源目录只能包含 Java
源代码。这些目录不一定是存在的,或是里面包含有什么内容;Scala
插件只会进行编译,而不管它发现什么。
The Scala plugin assumes the project layout shown below. All the Scala source directories can contain
Scala
and
Java code. The Java source directories may only contain Java source code.
None of these directories need to exist or have anything in them; the Scala plugin will simply compile
whatever it finds.
表 25.3. Scala 插件 - 项目布局
Table 25.3. Scala plugin - project layout
目录 Directory |
意义 Meaning |
src/main/java
|
产品的Java源代码 Production Java source |
src/main/resources
|
产品的资源 Production resources |
src/main/scala
|
Production Scala 源代码。此外可能包含联合编译的 Java 源代码。 Production Scala sources. May also contain Java sources for joint compilation. |
src/test/java
|
Java 测试源代码 Test Java source |
src/test/resources
|
测试资源 Test resources |
src/test/scala
|
Test Scala 源代码。此外可能包含联合编译的 Java 源代码。 Test Scala sources. May also contain Java sources for joint compilation. |
src/
|
给定的源集的Java源代码 Java source for the given source set |
src/
|
给定的源集的资源 Resources for the given source set |
src/
|
给定的source set 的 Scala 源代码。此外可能包含联合编译的 Java 源代码。 Scala sources for the given source set. May also contain Java sources for joint compilation. |
和 Java 插件一样,Scala 插件允许把 Scala 的production 和test
的源文件配置为自定义的位置。
Just like the Java plugin, the Scala plugin allows to configure custom locations for Scala production and test sources.
示例 24.2. 自定义 Scala 源文件布局
Example 25.2. Custom Scala source layout
build.gradle
sourceSets { main { scala { srcDirs = ['src/scala'] } } test { scala { srcDirs = ['test/scala'] } } }
Scala 项目需要声明一个
scala-library
依赖项。这个依赖会在编译和运行的类路径时用到。它还将用于分别获取Scala
编译器及 Scaladoc 工具。
[
12]
Scala projects need to declare a
scala-library
dependency. This dependency will then be used on compile and
runtime class paths. It will also be used to get hold of the Scala compiler and Scaladoc tool, respectively. [
12
]
如果 Scala 用于production 代码,
scala-library
依赖应该添加到
compile
的配置中:
If Scala is used for production code, the
scala-library
dependency should be added to the
compile
configuration:
示例 25.3. 为production 代码定义一个Scala 依赖
Example 25.3. Declaring a Scala dependency for production code
build.gradle
repositories {
mavenCentral()
}
dependencies {
compile 'org.scala-lang:scala-library:2.9.1'
}
如果 Scala 仅用于测试代码,
scala-library
依赖应被添加到
testCompile
配置中:
If Scala is only used for test code, the
scala-library
dependency should be added to the
testCompile
configuration:
示例 25.4. 为 test 代码定义一个Scala 依赖
Example 25.4. Declaring a Scala dependency for test code
build.gradle
dependencies {
testCompile "org.scala-lang:scala-library:2.9.2"
}
ScalaCompile
和
ScalaDoc
tasks 会以两种方式使用 Scala: 在它们的
classpath
以及
scalaClasspath
上。前者用于在源代码中查找类的引用,通常会包含
scala-library
和其他库。后者用来分别加载和执行 Scala 编译器和 Scala
工具,并且应该只包含
scala-library
及其依赖项。
ScalaCompile
and
ScalaDoc
tasks consume Scala in two ways: on their
classpath
,
and on their
scalaClasspath
. The former is used to locate classes referenced by the source code, and will typically
contain
scala-library
along with other libraries. The latter is used to load and execute the Scala compiler
and Scaladoc tool, respectively, and should only contain the
scala-compiler
library and its dependencies.
除非显式配置了一个 task 的
scalaClasspath
,否则 Scala(基础)插件会尝试推断该 task 的
classpath
。以如下方式进行:
Unless a task's
scalaClasspath
is configured explicitly, the Scala (base) plugin will try to infer it
from the task's
classpath
. This is done as follows:
classpath
中找到
scala-library
Jar
,并且该项目已经在至少一个仓库中声明了它,那么相应的
scala-compiler
的仓库依赖将添加到
scalaClasspath
中。scala-library
Jar is found on
classpath
, and the project has at least one repository declared,
a corresponding
scala-compiler
repository dependency will be added to
scalaClasspath
.
scalaClasspath
。scalaClasspath
could not be inferred.
Scala 插件没有向 project 添加任何的公约属性。
The Scala plugin does not add any convention properties to the project.
Scala 的插件向 project 的每一个source set
添加了下列的公约属性。你可以在你的构建脚本中,把这些属性当成是source set
对象中的属性一样使用 (见
第 21.3,“公约”)。
The Scala plugin adds the following convention properties to each source set in the project. You can
use these properties in your build script as though they were properties of the source set object (see
Section 21.3, “Conventions”
).
表 25.4. Scala 插件 - source set 属性
Table 25.4. Scala plugin - source set properties
属性名称 Property name |
类型 Type |
默认值 Default value |
描述 Description |
scala
|
SourceDirectorySet
(read-only)
|
非空 Not null |
该source set 中的 Scala 源文件。包含在 Scala 源目录中找到的所有的
.scala 和
.java 文件,并排除所有其他类型的文件。The Scala source files of this source set. Contains all .scala
and
.java
files found in the Scala source directories, and excludes all other
types of files.
|
scala.srcDirs
|
Set<File> . 可以使用
16.5
章节,"指定一组输入文件"中所讲到的任何一个来设置。Set<File>
. Can set using anything described in
Section 16.5, “Specifying a set of input files”
.
|
[
|
源目录包含该 source set 中的 Scala 源文件。此外可能还包含用于联合编译的 Java
源文件。 The source directories containing the Scala source files of this source set. May also contain Java source files for joint compilation. |
allScala
|
FileTree
(read-only)
|
非空 Not null |
该source set 中的所有 Scala 源文件。包含在 Scala 源目录中找到的所有的
.scala 文件。All Scala source files of this source set. Contains only the .scala
files
found in the Scala source directories.
|
这些属性由一个
ScalaSourceSet
的约定对象提供。
These convention properties are provided by a convention object of type
ScalaSourceSet
.
Scala 的插件还修改了一些 source set 的属性:
The Scala plugin also modifies some source set properties:
表 25.5. Scala 插件 - source set 属性
Table 25.5. Scala plugin - source set properties
属性名称 Property name |
修改的内容 Change |
allJava
|
添加在 Scala 源目录中找到的所有
.java 文件。Adds all .java
files found in the Scala source directories.
|
allSource
|
添加在 Scala 的源目录中找到的所有源文件。 Adds all source files found in the Scala source directories. |
Scala 插件包含了对
fsc,即 Fast Scala Compiler
的支持。
fsc
运行在一个单独的进程中,并且可以显著地提高编译速度。
The Scala plugin includes support for
fsc
,
the Fast Scala Compiler.
fsc
runs in a separate daemon process and can speed up
compilation significantly.
示例 25.5. 启用 Fast Scala Compiler
Example 25.5. Enabling the Fast Scala Compiler
build.gradle
compileScala { scalaCompileOptions.useCompileDaemon = true // optionally specify host and port of the daemon: scalaCompileOptions.daemonServer = "localhost:4243" }
注意,每当
fsc
的编译类路径的
内容
发生变化时,它都需要重新启动。(它本身不会去检测编译类路径的更改。)这使得它不太适合于多项目的构建。
Note that
fsc
expects to be restarted whenever the
contents
of its
compile class path change. (It does detect changes to the compile class path itself.) This makes it
less suitable for multi-project builds.
当
scalaCompileOptions.fork
设置为
true
时,编译会在外部进程中进行。fork
的详细情况依赖于所使用的编译器。基于 Ant 的编译器 (
scalaCompileOptions.useAnt = true
) 将为每个
ScalaCompile
任务fork 一个新进程,而默认情况下它不进行fork。基于 Zinc
的编译器 (
scalaCompileOptions.useAnt = false
) 将利用 Gradle
编译器守护进程,且默认情况下也是这样。
When
scalaCompileOptions.fork
is set to
true
, compilation will take place
in an external process. The details of forking depend on which compiler is used. The Ant based compiler
(
scalaCompileOptions.useAnt = true
) will fork a new process for every
ScalaCompile
task,
and does not fork by default. The Zinc based compiler (
scalaCompileOptions.useAnt = false
) will leverage
the Gradle compiler daemon, and does so by default.
外部过程默认使用JVM 的的默认内存设置。如果要调整内存设置,请根据需要配置
scalaCompileOptions.forkOptions
:
Memory settings for the external process default to the JVM's defaults. To adjust memory settings,
configure
scalaCompileOptions.forkOptions
as needed:
示例 25.6. 调整内存设置
Example 25.6. Adjusting memory settings
build.gradle
tasks.withType(ScalaCompile) { configure(scalaCompileOptions.forkOptions) { memoryMaximumSize = '1g' jvmArgs = ['-XX:MaxPermSize=512m'] } }
增量编译是只编译那些源代码在上一次编译之后有修改的类,及那些受这些修改影响到的类,它可以大大减少
Scala
的编译时间。频繁编译代码的增量部分是非常有用的,因为在开发时我们经常要这样做。
By compiling only classes whose source code has changed since the previous compilation, and classes affected by these changes,
incremental compilation can significantly reduce Scala compilation time. It is particularly effective when frequently compiling
small code increments, as is often done at development time.
Scala 插件现在通过集成
Zinc 来支持增量编译, 它是
sbt增量 Scala
编译器的一个单机版本。若要把
ScalaCompile
任务从默认的基于 Ant 的编译器切换为新的基于 Zinc
的编译器,需要将
scalaCompileOptions.useAnt
设置为
false
:
The Scala plugin now supports incremental compilation by integrating with
Zinc
,
a standalone version of
sbt
's incremental Scala compiler. To switch the
ScalaCompile
task from the default Ant based compiler to the new Zinc based compiler, set
scalaCompileOptions.useAnt
to
false
:
示例 25.7. 激活基于 Zinc 编译器
Example 25.7. Activating the Zinc based compiler
build.gradle
tasks.withType(ScalaCompile) { scalaCompileOptions.useAnt = false }
除非在
API
文档中另有说明,否则基于 Zinc 的据编译器支持与基于 Ant
的编译器完全相同的配置选项。但是,要注意的是,Zinc 编译器需要 Java 6
或其以上版本来运行。这意味着 Gradle 本身要使用 Java 6 或其以上版本。
Except where noted in the
API documentation
,
the Zinc based compiler supports exactly the same configuration options as the Ant based compiler. Note, however, that the Zinc compiler requires
Java 6 or higher to run. This means that Gradle itself has to be run with Java 6 or higher.
Scala 插件添加了一个名为
zinc
的配置,以解析 Zinc 库及其依赖。如果要重写 Gradle
默认情况下使用的 Zinc 版本,请添加一个显式的 Zinc 依赖项 (例如
zinc "com.typesafe.zinc:zinc:0.1.4"
)。无论使用哪一个 Zinc 版本,Zinc
都是使用在
scalaTools
配置上找到的 Scala 编译器。
The Scala plugin adds a configuration named
zinc
to resolve the Zinc library and its dependencies. To override the
Zinc version that Gradle uses by default, add an explicit Zinc dependency (for example
zinc "com.typesafe.zinc:zinc:0.1.4"
).
Regardless of which Zinc version is used, Zinc will always use the Scala compiler found on the
scalaTools
configuration.
就像Gradle 上基于Ant 的编译器一样,基于 Zinc 的编译器支持 Java 和 Scala
代码的联合编译。默认情况下,在
src/main/scala
下的所有 Java 和 Scala 代码都会进行联合编译。使用基于 Zinc
的编译器时,即使是 Java 代码也将会进行增量编译。
Just like Gradle's Ant based compiler, the Zinc based compiler supports joint compilation of Java and Scala code. By default, all Java and Scala code
under
src/main/scala
will participate in joint compilation. With the Zinc based compiler, even Java code will be compiled incrementally.
增量编译需要源代码的相关性分析。解析结果进入由
scalaCompileOptions.incrementalOptions.analysisFile
所指定的文件(它有一个合理的默认值)。在多项目构建中,分析文件被传递给下游的
ScalaCompile
任务,以启用跨项目的增量编译。对于由 Scala 插件添加的
ScalaCompile
任务,无需对这一点进行配置。对于其他的
ScalaCompile
任务,需要根据类文件夹或 Jar archive
的代码中,是哪一个的代码被传递给
ScalaCompile
任务的下游类路径,把
ScalaCompileOptions.incrementalOptions.publishedCode
配置为指向它们。注意,如果
publishedCode
设置不正确,上游代码发生变化时下游任务可能不会重新编译代码,导致编译结果不正确。
Incremental compilation requires dependency analysis of the source code. The results of this analysis are stored in the file designated
by
scalaCompileOptions.incrementalOptions.analysisFile
(which has a sensible default). In a multi-project build, analysis
files are passed on to downstream
ScalaCompile
tasks to enable incremental compilation across project boundaries. For
ScalaCompile
tasks added by the Scala plugin, no configuration is necessary to make this work. For other
ScalaCompile
tasks,
scalaCompileOptions.incrementalOptions.publishedCode
needs to be configured to point
to the classes folder or Jar archive by which the code is passed on to compile class paths of downstream
ScalaCompile
tasks.
Note that if
publishedCode
is not set correctly, downstream tasks may not recompile code affected by upstream changes,
leading to incorrect compilation results.
由于依赖分析的系统开销,一次干净的编译或在代码有了较大的更改之后的编译,可能花费的时间要长于使用基于
Ant 的编译器。对于 CI 构建和版本的构建中,我们目前推荐使用基于 Ant 的编译器。
Due to the overhead of dependency analysis, a clean compilation or a compilation after a larger code change may take longer than with the Ant based compiler.
For CI builds and release builds, we currently recommend to use the Ant based compiler.
注意现在 Zinc 基于守护进程模式的Nailgun 还不支持。相反,我们打算加强 Gradle
自己的编译器守护进程,使得在跨 Gradle 调用时继续存活,利用同一个 Scala 编译器。这将会为
Scala 编译带来另一个方面上的明显加速。
Note that Zinc's Nailgun based daemon mode is not supported. Instead, we plan to enhance Gradle's own compiler daemon to stay alive across Gradle
invocations, reusing the same Scala compiler. This is expected to yield another significant speedup for Scala compilation.
当 Eclipse 插件遇到 Scala 项目时,它将添加额外的配置,使得项目能够在使用 Scala IDE
时开箱即用。具体而言,该插件添加一个 Scala 性质和依赖的容器。
When the Eclipse plugin encounters a Scala project, it adds additional configuration to make the project work with Scala IDE out of the box.
Specifically, the plugin adds a Scala nature and dependency container.
当 IDEA 插件遇到 Scala 项目时,它将添加额外的配置,使得项目能够在使用 IDEA
时开箱即用。具体而言,该插件添加了一个 Scala facet 和一个匹配项目的类路径上的 Scala
版本的 Scala 编译器类库。
When the IDEA plugin encounters a Scala project, it adds additional configuration to make the project work with IDEA out of the box. Specifically,
the plugin adds a Scala facet and a Scala compiler library that matches the Scala version on the project's class path.