Gradle 工具鏈對 JVM 項目的支持
一、簡介
在本教程中,我們將探討 Gradle 工具鏈對 JVM 項目的支持。
我們首先要了解此功能背後的動機。然後,我們將定義它並通過實際示例進行嘗試。
2. 工具鏈背後的推理
在討論什麼是工具鏈之前,我們需要先談談它存在的原因。假設我們要編寫一個 Java 項目。我們的 Java 項目可能會包含一些測試。所以至少我們想要編譯我們的代碼並運行測試。我們添加java
內置 Gradle 插件並指定我們想要的字節碼版本:
plugins {
id 'java'
}
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
此外,如果需要,我們可以告訴 Gradle 將我們的測試類編譯成不同的字節碼版本:
tasks {
compileTestJava {
sourceCompatibility = JavaVersion.VERSION_1_7
targetCompatibility = JavaVersion.VERSION_1_7
}
}
到目前為止,一切都很好。唯一的細微差別是,為了編譯我們的源代碼/測試類,Gradle 使用了自己的 JDK,即它在.不過,我們可以通過指定要使用的確切可執行文件來解決這個問題:
compileTestJava.getOptions().setFork(true)
compileTestJava.getOptions().getForkOptions().setExecutable('/home/mpolivaha/.jdks/corretto-17.0.4.1/bin/javac')
compileJava.getOptions().setFork(true)
compileJava.getOptions().getForkOptions().setExecutable('/home/mpolivaha/.jdks/corretto-17.0.4.1/bin/javac')
但是,如果我們在構建過程中使用各種JDK,就會出現問題。
例如,假設我們必須在發布之前在客戶的 JDK 上測試我們的 Java 應用程序。這些 JDK 可能來自不同的供應商,儘管符合規範,但細節上有所不同。理論上我們可以在沒有工具鏈的情況下解決這個問題,但這將是一個更加複雜的解決方案。工具鏈使構建的配置變得更容易,這需要各種 JDK 來實現不同的目的。
3. 工具鏈定義
從 6.7 版本開始,Gradle 引入了 JVM Toolchains 功能。不過,工具鏈這個概念並不新鮮。因此,它在 Maven 中存在了相當長的一段時間。一般來說,工具鍊是構建、測試和運行軟件所需的一組工具和二進製文件。因此,在 Java 中,我們可以說 JDK 是 Java 工具鏈,因為它允許編譯、測試和運行 Java 程序。
我們可以在項目級別定義工具鏈,因此在本例中它將如下所示:
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
vendor = JvmVendorSpec.AMAZON
implementation = JvmImplementation.VENDOR_SPECIFIC
}
}
這樣,我們就可以指定所需的Java版本、JDK的供應商以及該供應商的JVM的具體實現。為了使工具鏈規范正確, 我們至少必須設置版本.
Gradle 在處理工具鏈時所做的事情很簡單。首先,它會嘗試在本地查找所請求的工具鏈;為此有一個特定的算法。如果 Gradle 在本地找不到所需的工具鏈,它會嘗試遠程查找並下載。如果 Gradle 無法遠程找到所需的工具鏈,則構建失敗。
還值得一提的是,有時我們想要禁用自動配置。我們可以通過將-Porg.gradle.java.installations.auto-download=false
傳遞到gradle
可執行文件中來做到這一點。在這種情況下,如果本地無法找到工具鏈,Gradle 構建將會失敗。
4. 任務級別的工具鏈
工具鏈的真正威力在於能夠按任務方式指定 JDK 安裝:
tasks.named('compileJava').get().configure {
javaCompiler = javaToolchains.compilerFor {
languageVersion = JavaLanguageVersion.of(17)
vendor = JvmVendorSpec.AMAZON
implementation = JvmImplementation.VENDOR_SPECIFIC
}
}
tasks.register("testOnAmazonJdk", Test.class, {
javaLauncher = javaToolchains.launcherFor {
languageVersion = JavaLanguageVersion.of(17)
vendor = JvmVendorSpec.AMAZON
}
})
tasks.named("testClasses").get().finalizedBy("testOnAmazonJdk")
在上面的示例中,我們將compileJava 任務配置為在Oracle JDK 15 上運行。我們還創建了testOnAmazonJdk
任務,該任務將在testClasses
任務之後立即運行。請注意,這個新任務也在單獨的 JDK 上執行。
5. 本地工具鏈識別
最後,Gradle 允許我們使用以下命令查看當前項目可用的工具鏈的本地安裝:
gradle javaToolchains
首先,Gradle 將在當前位置搜索構建文件。然後它將列出根據構建文件中指定的位置/規則找到的工具鏈。
六,結論
在本快速教程中,我們回顧了 Gradle 工具鏈功能。此功能簡化了構建過程中使用不同 JDK 的過程(如果適用)。它從 Gradle 6.7 開始提供,我們可以在任務級別應用它,這使得這個功能非常有價值。
與往常一樣,本文的源代碼可以在 GitHub 上找到。