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 编译任务的依赖关系的信息可在此处找到。

compileGroovyGroovy 编译

依赖于取决于compileJava

编译生产 Groovy 源文件。

compileTestGroovyGroovy 编译

依赖于取决于compileTestJava

编译测试 Groovy 源文件。

compileSourceSetGroovyGroovy 编译

依赖于取决于compileSourceSetJava

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

groovydocGroovydoc

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

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

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

classes

compileGroovy

testClasses

compileTestGroovy

sourceSetClasses

compileSourceSetGroovy

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

项目布局

Groovy 插件采用Groovy Layout中显示的项目布局。所有 Groovy 源目录都可以包含 GroovyJava 代码。 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 — 源集属性

groovyGroovySourceDirectorySet(只读)

默认值:不为空

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

groovy.srcDirsSet<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 工具引入的相同约定。