3

我想使用默认系统 JRE 运行 Gradle,在我的例子中是 Java8。

在构建中,我想使用带有 option.fork=true 的特定 JDK 13

compileJava {
    options.encoding = 'UTF-8'
    sourceCompatibility = 13
    targetCompatibility = 13
    options.compilerArgs << "-parameters"
    options.compilerArgs << "--release" << "13"
    options.compilerArgs << "--enable-preview"
    options.fork = true
    options.forkOptions.executable = "${projectDir}/tools/java/bin/javac.exe"
}

当我使用 JRE 8 开始 gradle 时,这会失败并显示消息:

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':compileJava'.
> Could not target platform: 'Java SE 13' using tool chain: 'JDK 8 (1.8)'.

但是当我将 JAVA_HOME 设置为 JDK 13 时,它会成功运行。

有没有办法让这个运行,Gradle 从 JRE8 开始,但使用 JDK13 进行构建?

坦率

4

1 回答 1

3

Gradle 有一个targetCompatibility不高于当前运行的 Java 版本的检查。老实说,我不知道为什么当您将编译器分叉到较新版本时它会检查这个(如果有的话,它可能应该检查那个版本)。但也许有一个很好的理由。

--release但是,当您使用标志时,这两个属性也是完全多余的。这已经告诉编译器它应该为该特定版本生成字节码。我什至不认为编译器支持同时拥有sourcetarget参数--release。因此,如果您删除两个属性sourceCompatibilitytargetCompatibility,它应该可以工作。

此外,Java 编译器默认为相同版本编译,因此您也不需要 --release 标志。

最后,您只配置了“主”源集编译,您也应该为“测试”做同样的事情。虽然它可能并不重要,但您可能还想配置JavaDoc任何类型的任务JavaExec以使用 Java 13,否则它们将默认使用 Java 8。

因此,为了将所有这些结合在一起,当针对比 Gradle 使用的更高版本的 Java 时,请使用以下内容:

// Paths for the various executables in the Java 'bin' directory
def javaHome = "${projectDir}/tools/java"
def javaCompilerPath = "$javaHome/bin/javac.exe"
def javaExecutablePath = "$javaHome/bin/java.exe"
def javaDocPath = "$javaHome/bin/javadoc.exe"

tasks.withType(AbstractCompile) { // Configures all compile tasks (both for main and test)
    // The sourceCompatibility and targetCompatibility properties have been removed
    options.encoding = 'UTF-8'
    options.compilerArgs.addAll(["-parameters", "--enable-preview"]) // The --release flag is optional when used for the same version
    options.fork = true
    options.forkOptions.executable = javaCompilerPath
    options.forkOptions.javaHome = file(javaHome)
}

tasks.withType(Javadoc) { // Configures JavaDoc to use the tool in Java 13
    executable = javaDocPath
}

tasks.withType(JavaExec) { // Only needed if you have any tasks of this type
    executable = javaExecutablePath
}

当 Gradle 6.0 发布时,大约一周后,它将支持 Java 13,因此您不需要任何这些(直到您决定在 Gradle 获得对它的支持之前更新到 Java 14)。

于 2019-10-07T16:09:21.303 回答