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 編譯任務相依性的資訊,請參閱 此處

compileGroovyGroovyCompile

相依於compileJava

編譯製作用 Groovy 來源檔案。

compileTestGroovyGroovyCompile

依賴compileTestJava

編譯測試 Groovy 原始檔。

compileSourceSetGroovyGroovyCompile

依賴compileSourceSetJava

編譯給定原始檔組的 Groovy 原始檔。

groovydocGroovydoc

為製作 Groovy 原始檔產生 API 文件。

Groovy 外掛會將下列依賴關係加入 Java 外掛所加入的任務。

表 1. Groovy 外掛 - 其他任務依賴關係
任務名稱 依賴關係

classes

compileGroovy

testClasses

compileTestGroovy

sourceSetClasses

compileSourceSetGroovy

groovyPluginTasks
圖 1. Groovy 外掛 - 任務

專案配置

Groovy 外掛假設專案配置顯示在 Groovy 配置 中。所有 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 的自動組態

GroovyCompileGroovydoc 任務以兩種方式使用 Groovy 程式碼:在它們的 classpathgroovyClasspath 中。前者用於尋找原始程式碼引用的類別,通常會包含 Groovy 函式庫和其他函式庫。後者用於載入和執行 Groovy 編譯器和 Groovydoc 工具,且僅應包含 Groovy 函式庫及其相依性。

除非任務的 groovyClasspath 明確組態,否則 Groovy (基本) 外掛程式會嘗試從任務的 classpath 推斷它。執行方式如下

  • 如果在 classpath 中找到 groovy-all(-indy) Jar,該 jar 會新增至 groovyClasspath

  • 如果在 classpath 中找到 groovy(-indy) jar,且專案至少宣告一個儲存庫,則會將對應的 groovy(-indy) 儲存庫相依性新增至 groovyClasspath

  • 否則,任務執行會失敗,並顯示無法推斷 groovyClasspath 的訊息。

請注意,每個 jar 的「-indy」變體是指支援 invokedynamic 的版本。

慣例屬性

Groovy 外掛程式不會將任何慣例屬性新增至專案。

來源設定屬性

Groovy 外掛程式會將下列擴充套件新增至專案中的每個來源設定。您可以在建置指令碼中使用這些屬性,就像它們是來源設定物件的屬性一樣。

Groovy 外掛程式 — 來源設定屬性

groovyGroovySourceDirectorySet(唯讀)

預設值:非 null

此來源組的 Groovy 來源檔案。包含在 Groovy 來源目錄中找到的所有 .groovy.java 檔案,並排除所有其他類型的檔案。

groovy.srcDirsSet<File>

預設值[projectDir/src/name/groovy]

包含此來源組的 Groovy 來源檔案的來源目錄。也可以包含 Java 來源檔案以進行聯合編譯。可以使用 指定多個檔案 中所述的任何內容來設定。

allGroovyFileTree(唯讀)

預設值:非 null

此來源組的所有 Groovy 來源檔案。僅包含在 Groovy 來源目錄中找到的 .groovy 檔案。

這些屬性是由 GroovySourceSet 類型的慣例物件所提供的。

Groovy 外掛也修改了一些來源組屬性

Groovy 外掛 - 已修改的來源組屬性

屬性名稱 變更

allJava

新增在 Groovy 來源目錄中找到的所有 .java 檔案。

allSource

新增在 Groovy 來源目錄中找到的所有來源檔案。

GroovyCompile

Groovy 外掛會為專案中的每個來源組新增一個 GroovyCompile 工作。此工作類型透過延伸 AbstractCompileJavaCompile 工作有許多共同點(請參閱 相關的 Java 外掛區段)。GroovyCompile 工作支援官方 Groovy 編譯器的多數設定選項。此工作也可以利用 Java 工具鏈支援

表 2. Groovy 外掛 - GroovyCompile 屬性
工作屬性 類型 預設值

classpath

FileCollection

sourceSet.compileClasspath

source

FileTree。可以使用 指定多個檔案 中所述的任何內容來設定。

sourceSet.groovy

destinationDirectory

檔案.

sourceSet.groovy.destinationDirectory

groovyClasspath

FileCollection

若非空,則為groovy 組態;否則為在 classpath 上找到的 Groovy 函式庫

javaLauncher

Property<JavaLauncher>,請參閱 工具鏈文件

無,但如果在 java 延伸模組上定義工具鏈,則會進行組態。

避免編譯

警告:自 Gradle 5.6 起,Groovy 避免編譯為孵化功能。已知有某些不準確之處,因此請自行承擔風險啟用。

若要啟用 Groovy 避免編譯的孵化支援,請將 enableFeaturePreview 新增至設定檔

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

如果相依專案已以 ABI 相容方式變更(僅其私人 API 已變更),則 Groovy 編譯工作會為最新狀態。這表示如果專案 A 相依於專案 B,且 B 中的類別已以 ABI 相容方式變更(通常僅變更方法主體),則 Gradle 就不會重新編譯 A

請參閱 Java 避免編譯,以取得詳細的變更類型清單,這些變更不會影響 ABI,且會被忽略。

然而,類似於 Java 的註解處理,有許多方法可以 自訂 Groovy 編譯程序,而實作細節至關重要。一些著名的範例為 Groovy AST 轉換。在這些情況下,這些相依項必須在稱為 astTransformationClasspath 的 classpath 中個別宣告

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 原始檔,這也會設定 JavaCompile 使用正確的 Java 編譯器,如 Java 外掛程式 文件中所示。

範例:為 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 工具 導入相同的慣例。