Запустите Gradle с Java8 и скомпилируйте Java13 с помощью fork - PullRequest
1 голос
/ 05 октября 2019

Я хочу запустить Gradle с системной JRE по умолчанию, в моем случае Java8.

И в сборке я хочу использовать определенный JDK 13 с параметром option.fork = true

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"
}

Когда я запускаю gradle с JRE 8, это завершается ошибкой с сообщением:

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 для сборки?

Frank

1 Ответ

1 голос
/ 07 октября 2019

Gradle проверяет, что targetCompatibility не выше, чем текущая версия Java. Честно говоря, я не знаю, почему он проверяет это, когда вы переходите на компилятор с более новой версией (возможно, он должен проверить эту версию, если что-нибудь вместо этого). Но, возможно, для этого есть веская причина.

Однако эти два свойства также полностью избыточны при использовании флага --release. Это уже говорит компилятору, что он должен генерировать байт-код для этой конкретной версии. Я даже не думаю, что компилятор поддерживает одновременное использование аргументов source и target вместе с --release. Поэтому, если вы удалите два свойства sourceCompatibility и targetCompatibility, это должно сработать.

Кроме того, компилятор Java по умолчанию компилируется для той же версии, поэтому вам также не нужен флаг --release.

Наконец, вы конфигурируете только основной набор исходных текстов, и вы должны сделать то же самое и для test. И хотя это может быть не важно, вы также можете настроить JavaDoc и любые задачи типа JavaExec на использование Java 13, или они по умолчанию будут использовать Java 8.

Итак, чтобы собрать все вместепри нацеливании на более высокую версию Java, чем та, которая используется для Gradle, используйте что-то вроде этого:

// 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, таквам это не нужно (пока вы не решите обновить Java 14 до того, как Gradle получит поддержку, разумеется).

...