Groovy 插件扩展了Java 插件以添加对Groovy项目的支持。它可以处理 Groovy 代码、混合 Groovy 和 Java 代码,甚至纯 Java 代码(尽管我们不一定建议将它用于后者)。该插件支持联合编译,允许您自由地混合和匹配 Groovy 和 Java 代码,并具有双向依赖关系。例如,Groovy 类可以扩展 Java 类,而 Java 类又扩展 Groovy 类。这使得可以使用最适合工作的语言,并在需要时用其他语言重写任何类。

请注意,如果您想从API/实现分离中受益,您还可以将该java-library插件应用到您的 Groovy 项目中。

用法

要使用 Groovy 插件,请在构建脚本中包含以下内容:

build.gradle.kts
plugins {
    groovy
}
build.gradle
plugins {
    id 'groovy'
}

任务

Groovy 插件将以下任务添加到项目中。有关更改 Java 编译任务的依赖关系的信息可在此处找到。

compileGroovy— Groovy 编译

依赖于取决于:compileJava

编译生产 Groovy 源文件。

compileTestGroovy— Groovy 编译

依赖于取决于:compileTestJava

编译测试 Groovy 源文件。

compileSourceSetGroovy— Groovy 编译

依赖于取决于:compileSourceSetJava

编译给定源集的 Groovy 源文件。

groovydoc— Groovydoc

为生产 Groovy 源文件生成 API 文档。

Groovy 插件将以下依赖项添加到 Java 插件添加的任务中。

表 1. Groovy 插件 - 其他任务依赖项
任务名称 依赖于取决于

classes

compileGroovy

testClasses

compileTestGroovy

sourceSetClasses

compileSourceSetGroovy

groovy插件任务
图 1. Groovy 插件 - 任务

项目布局

Groovy 插件采用Groovy Layout中显示的项目布局。所有 Groovy 源目录都可以包含 Groovy和Java 代码。 Java 源目录可能仅包含 Java 源代码。[ 1 ]这些目录都不需要存在或包含任何内容; Groovy 插件将简单地编译它找到的任何内容。

src/main/java

生产 Java 源代码。

src/main/resources

生产资源,例如 XML 和属性文件。

src/main/groovy

生产 Groovy 源代码。还可能包含用于联合编译的 Java 源文件。

src/test/java

测试 Java 源。

src/test/resources

测试资源。

src/test/groovy

测试 Groovy 源。还可能包含用于联合编译的 Java 源文件。

src/sourceSet/java

名为sourceSet的源集的 Java 源。

src/sourceSet/resources

名为sourceSet的源集的资源。

src/sourceSet/groovy

给定源集的 Groovy 源文件。还可能包含用于联合编译的 Java 源文件。

更改项目布局

就像 Java 插件一样,Groovy 插件允许您为 Groovy 生产和测试源文件配置自定义位置。

build.gradle.kts
sourceSets {
    main {
        groovy {
            setSrcDirs(listOf("src/groovy"))
        }
    }

    test {
        groovy {
            setSrcDirs(listOf("test/groovy"))
        }
    }
}
build.gradle
sourceSets {
    main {
        groovy {
            srcDirs = ['src/groovy']
        }
    }

    test {
        groovy {
            srcDirs = ['test/groovy']
        }
    }
}

依赖管理

由于 Gradle 的构建语言基于 Groovy,并且 Gradle 的部分内容是用 Groovy 实现的,因此 Gradle 已经附带了 Groovy 库。尽管如此,Groovy 项目需要显式声明 Groovy 依赖项。然后,此依赖项将用于编译和运行时类路径。它还将分别用于获取 Groovy 编译器和 Groovydoc 工具。

如果 Groovy 用于生产代码,则应将 Groovy 依赖项添加到配置中implementation:

build.gradle.kts
repositories {
    mavenCentral()
}

dependencies {
    implementation("org.codehaus.groovy:groovy-all:2.4.15")
}
build.gradle
repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.codehaus.groovy:groovy-all:2.4.15'
}

如果 Groovy 仅用于测试代码,则应将 Groovy 依赖项添加到配置中testImplementation:

build.gradle.kts
dependencies {
    testImplementation("org.codehaus.groovy:groovy-all:2.4.15")
}
build.gradle
dependencies {
    testImplementation 'org.codehaus.groovy:groovy-all:2.4.15'
}

要使用 Gradle 附带的 Groovy 库,请声明localGroovy()依赖项。请注意,不同的 Gradle 版本附带不同的 Groovy 版本;因此,使用的localGroovy()安全性不如声明常规 Groovy 依赖项。

build.gradle.kts
dependencies {
    implementation(localGroovy())
}
build.gradle
dependencies {
    implementation localGroovy()
}

自动配置groovyClasspath

GroovyCompile和任务Groovydoc以两种方式使用 Groovy 代码:在它们的classpath和 在它们的groovyClasspath.前者用于定位源代码引用的类,通常包含 Groovy 库以及其他库。后者分别用于加载和执行 Groovy 编译器和 Groovydoc 工具,并且应该只包含 Groovy 库及其依赖项。

除非显式配置任务groovyClasspath,否则 Groovy(基本)插件将尝试从任务的classpath.这是按如下方式完成的:

  • 如果groovy-all(-indy)在 上找到 Jar classpath,则该 Jar 将被添加到groovyClasspath。

  • 如果groovy(-indy)在 上找到一个 jar classpath,并且该项目至少声明了一个存储库,groovy(-indy)则会将相应的存储库依赖项添加到 中groovyClasspath。

  • 否则,任务执行将失败,并显示一条消息,指出groovyClasspath无法推断。

请注意,每个 jar 的“ -indy”变体是指支持的版本invokedynamic。

约定属性

Groovy 插件不会向项目添加任何约定属性。

源集属性

Groovy 插件将以下扩展添加到项目中的每个源集。您可以在构建脚本中使用这些属性,就像它们是源集对象的属性一样。

Groovy Plugin — 源集属性

groovy— GroovySourceDirectorySet(只读)

默认值:不为空

该源集的 Groovy 源文件。包含在 Groovy 源目录中找到的所有文件,并排除所有其他类型的文件.groovy。.java

groovy.srcDirs—Set<File>

默认值:[projectDir/src/name/groovy]

包含此源集的 Groovy 源文件的源目录。还可能包含用于联合编译的 Java 源文件。可以使用指定多个文件中描述的任何内容进行设置。

allGroovy—文件树(只读)

默认值:不为空

该源集的所有 Groovy 源文件。仅包含.groovy在 Groovy 源目录中找到的文件。

这些属性由GroovySourceSet类型的约定对象提供。

Groovy 插件还修改了一些源集属性:

Groovy 插件 - 修改源集属性

物业名称 改变

allJava

添加.java在 Groovy 源目录中找到的所有文件。

allSource

添加在 Groovy 源目录中找到的所有源文件。

Groovy编译

Groovy 插件为项目中的每个源集添加一个GroovyCompileJavaCompile任务。通过扩展,任务类型与任务有很多共享AbstractCompile(请参阅相关的 Java 插件部分)。该GroovyCompile任务支持官方 Groovy 编译器的大多数配置选项。该任务还可以利用Java 工具链支持。

表 2. Groovy 插件 - GroovyCompile 属性
任务属性 类型 默认值

classpath

文件集合

sourceSet.compileClasspath

source

文件树。可以使用指定多个文件中描述的任何内容进行设置。

sourceSet.groovy

destinationDirectory

File。

sourceSet.groovy.destinationDirectory

groovyClasspath

文件集合

groovy如果非空则配置;在classpath其他地方找到的 Groovy 库

javaLauncher

Property<JavaLauncher>,请参阅工具链文档。

如果在扩展上定义了工具链,则不会配置任何内容java。

避免编译

注意:Groovy 编译避免是自 Gradle 5.6 以来的一个孵化功能。存在已知的不准确之处,因此请自行承担启用它的风险。

要启用对避免 Groovy 编译的孵化支持,请enableFeaturePreview在您的设置文件中添加:

settings.gradle
enableFeaturePreview('GROOVY_COMPILATION_AVOIDANCE')
settings.gradle.kts
enableFeaturePreview("GROOVY_COMPILATION_AVOIDANCE")

如果依赖项目以ABI兼容方式发生更改(仅其私有 API 发生更改),则 Groovy 编译任务将是最新的。这意味着,如果项目A依赖于项目B,并且其中的类B以 ABI 兼容的方式更改(通常仅更改方法的主体),则 Gradle 将不会重新编译A.

有关不影响 ABI 且被忽略的更改类型的详细列表,请参阅Java 编译避免。

然而,与Java的注释处理类似,有多种方法可以定制Groovy编译过程,其中实现细节很重要。一些著名的例子是Groovy AST 转换。在这些情况下,必须在名为的类路径中单独声明这些依赖项astTransformationClasspath:

build.gradle.kts
val astTransformation by configurations.creating
dependencies {
    astTransformation(project(":ast-transformation"))
}
tasks.withType<GroovyCompile>().configureEach {
    astTransformationClasspath.from(astTransformation)
}
build.gradle
configurations { astTransformation }
dependencies {
    astTransformation(project(":ast-transformation"))
}
tasks.withType(GroovyCompile).configureEach {
    astTransformationClasspath.from(configurations.astTransformation)
}

增量 Groovy 编译

从 5.6 开始,Gradle 引入了一个实验性增量 Groovy 编译器。要为 Groovy 启用增量编译,您需要:

buildSrc/src/main/kotlin/myproject.groovy-conventions.gradle.kts
tasks.withType<GroovyCompile>().configureEach {
    options.isIncremental = true
    options.incrementalAfterFailure = true
}
buildSrc/src/main/groovy/myproject.groovy-conventions.gradle
tasks.withType(GroovyCompile).configureEach {
    options.incremental = true
    options.incrementalAfterFailure = true
}

这会给您带来以下好处:

  • 增量构建要快得多。

  • 如果仅更改一小部分 Groovy 源文件,则仅重新编译受影响的源文件。不需要重新编译的类在输出目录中保持不变。例如,如果您只更改了几个 Groovy 测试类,则无需重新编译所有 Groovy 测试源文件 — 只需重新编译更改的文件。

要了解增量编译的工作原理,请参阅增量 Java 编译以获取详细概述。请注意,与 Java 增量编译有几个不同之处:

Groovy 编译器不会保留@Retention生成的注释类字节码 ( GROOVY-9185 ),因此所有注释都是RUNTIME.这意味着对源保留注释的更改不会触发完全重新编译。

已知的问题

  • 对资源的更改不会触发重新编译,这可能会导致一些错误 - 例如扩展模块。

针对 Java 6 或 Java 7 的编译和测试

添加工具链支持后GroovyCompile,可以使用与运行 Gradle 不同的 Java 版本来编译 Groovy 代码。如果您还有 Java 源文件,这也将配置为使用正确的 Java 编译器,如Java 插件JavaCompile文档中所示。

示例:为 Groovy 配置 Java 7 构建

build.gradle.kts
java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(7)
    }
}
build.gradle
java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(7)
    }
}

1 . Gradle 使用与 Russel Winder 的Gant 工具引入的相同约定。