ChatGPT解决这个技术问题 Extra ChatGPT

如何告诉 Gradle 使用特定的 JDK 版本?

我无法弄清楚如何让这个工作。

设想:

我有一个用 gradle 构建的应用程序

该应用程序使用 JavaFX

我想要的是

使用一个变量(为每个开发人员机器定义),它指向一个 JDK 的安装,它将用于构建整个应用程序 / 测试 / ...

我想过拥有 gradle.properties 文件,定义变量。就像是

JAVA_HOME_FOR_MY_PROJECT=<path to my desired JDK>

我不想要的

将 JAVA_HOME 指向所需的 JDK

我可以接受很多建议:

一个定义系统环境变量的解决方案,我可以在我的 build.gradle 脚本中检查它

gradle.properties 中定义的变量

仅为构建上下文覆盖 JAVA_HOME 变量(类似于使用 JAVA_HOME=<我在其他地方定义的特殊 JDK 路径>)

其他我没想到的事情

问题:

如何将变量(如何定义,作为 gradle.properties 中的变量、系统环境变量……)连接到构建过程?

我有多个可用的 JDK7,需要指向一个特殊版本(最低 JDK_u 版本)。

任何答案都值得赞赏,我很感激每一个正确方向的提示。

您是否尝试在 gradle.properties 文件中设置 org.gradle.java.homelink
在 Eclipse 中,您可以在项目中创建“产品配置文件”,并且可以将 jdk 与您的产品一起打包。无需指定环境变量。
@RayStojonic:我只是试了一下,但是 gradle 仍然使用 JAVA_HOME JDK 进行构建 :(
@mdanaci:我真的希望我可以避免这种情况,因为老实说,我不想将 JDK 置于版本控制之下(如果我使用你的建议,这将是结果),因为任何开发人员都必须能够打包应用程序。另外,我以这种方式看到 CI 服务器存在问题。无论如何感谢您的建议:)
截至一年前,org.gradle.java.home 设置仅适用于 gradle 守护进程,显然......无论如何,尝试将 fork 设置为 true 并将 forkOptions.executable 设置为您要使用的 jdk:link

J
Jesse Barnum

两种方式

在 HOME_DIRECTORY 中的 .gradle 目录中的 gradle.properties 中设置 org.gradle.java.home=/path_to_jdk_directory

或者:

在你的 build.gradle compileJava.options.fork = true compileJava.options.forkOptions.executable = '/path_to_javac'


gradle.properties 也可以在项目级别定义,请参阅 gradle.org/docs/current/userguide/build_environment.html
如果您使用 gradle wrapper 执行,您也可以像 ./gradlew -Dorg.gradle.java.home=/path_to_jdk_directory 那样执行。如果您不想触摸 gradle.properties,那就太好了。
问题是如何设置 VERSION,而不是 JDK PATH,不是吗?
这样我就不能与其他在不同路径中拥有 java 的开发人员共享项目。
应该澄清选项 1 和 2 之间的区别:在选项 1 中,我们将 JVM 设置为 gradle 本身在其下运行,该 JVM 也将用于运行编译器任务(注意 javac 本身是一个 java 应用程序),而在选项 2 我们只是将 javac 设置为在其自己的 JVM 中生成。如果出于某种原因我们需要一个特定的 JVM 用于 gradle(例如,为 Java 8 编译给定的 gradle 插件),那么我们将不得不为编译过程分叉一个单独的 JVM。
m
mirmdasif

如果您在 gradle.properties 中添加 JDK_PATH,您的构建将依赖于该特定路径。而是使用以下命令行参数运行 gradle 任务

gradle build -Dorg.gradle.java.home=/JDK_PATH

这样,您的构建不依赖于某些具体路径。


在 Eclipse (Neon, 4.6) 中,您还可以在 Gradle 构建配置中设置 Java Home(请参阅选项卡“Java Home”)。如果您有 20 多个构建作业,这会有点乏味……我认为 Gradle 确实需要从系统配置中选择 Java 主目录!
这是一个公平的观点。我有一个名为 /usr/lib/java/jdk/home 的软链接,它指向安装的 current 版本。当然,当您想要特定版本(例如 u51)时,您需要具体说明路径。还有一些工具想要启动 gradle 似乎并没有在他们给 gradle 的环境中设置 JDK。而且我从来没有将 JDK 设置为当前的 JAVA_HOME,除非它是一个开发会话。
请注意,JDK_PATH 在 Windows 上不能有空格,即使它在引号中:您已将“程序文件”更改为 PROGRA~1(全部大写)或 DIR /X 告诉您的任何其他内容。
如果您使用 gradle wrapper,请调用如下命令
"... gradle itself (either standalone distribution or wrapper) uses JDK from JAVA_HOME environment variable or (if it is not set) from PATH". 我在调用 gradlew 之前指定了 JAVA_HOME 来解决这个问题。 (即env JAVA_HOME=/path/to/java gradlew war --stacktrace
G
Geert

对于在搜索 Maven 属性 maven.compiler.source(或 <source>1.8</source>)的 Gradle 等效项时出现在这里的人们:

在 build.gradle 你可以用

apply plugin: 'java'
sourceCompatibility = 1.8
targetCompatibility = 1.8

请参阅 Gradle documentation on this


@morgwai - 除了这不是问题的答案,它明确询问“我想要[是设置]一个变量(根据开发人员机器定义),该变量指向将用于构建的 JDK 的安装整个应用程序”。赞成的答案是正确的;这个答案是针对一个完全不同的问题。
诸如 Javadoc 任务之类的工具会忽略这一点(它尝试根据 Java 9 生成 javadoc,并在我的项目中指定使用 Java 8 的模块)
虽然不是这个问题的确切答案,但这种方式实际上不仅仅适用于一个系统。大多数搜索这个问题的人都希望看到这个答案,而不是其他答案。
我向 Google 询问“gradle 指定 jdk 版本”,它把我带到了这里。我实际上正在寻找的答案就是这个,无论问题的真正含义是什么。因为有用所以点赞。
“除了这不是问题的答案”,这个问题实际上问了两个问题......一个是“特定的JDK版本?” (按标题),另一个是“JDK 的安装”(按描述)。根据我的经验,前者通常更有用,因为较新的 JDK 通常可以针对较旧的 JDK 版本,从而允许现有位置实现标题(可能是意外)所要求的。
R
Raman

Gradle 6.7+ — 使用 Gradle 工具链支持

使用现代版本的 Gradle(版本 6.7+)执行此操作的正确方法是使用 Gradle Java Toolchain support

以下块,当 java 插件应用于当前项目时,将在所有 java 编译、测试和 javadoc 任务中使用 Java 11:

java {
  toolchain {
    languageVersion.set(JavaLanguageVersion.of(11))
  }
}

这也可以为 individual tasks 设置。

注意:对于 other tasks relying on a Java executable or Java home,使用编译器元数据设置适当的选项。请参阅下面的 Kotlin 插件示例,版本 1.5.30 之前。

Gradle 尝试通过几种常见机制来auto-detect 指定 JDK 的位置。如果自动检测不够,可以配置 Custom locations

科特林 1.5.30+

对于 Kotlin 1.5.30+,Kotlin 插件 supports toolchains directly

kotlin {
  jvmToolchain {
    (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of("11"))
  }
}

Kotlin 早期版本

为 1.5.30 之前的版本配置 Kotlin 编译器涉及使用工具链 API 来确定编译器,并将该信息传递给插件。其他基于编译器的插件可以以类似的方式进行配置。

val compiler = javaToolchains.compilerFor {
  languageVersion.set(JavaLanguageVersion.of(11))
}

tasks.withType<KotlinJvmCompile>().configureEach {
  kotlinOptions.jdkHome = compiler.get().metadata.installationPath.asFile.absolutePath
}

我需要删除 sourceCompatibility 和 targetCompatibility 吗?另外,如果我希望它使用特定的 java 更新运行,比如说 Java 8 Update 281 而不是 Java 8 Update 271,这可能吗?
@jumping_monkey 您无法在 java { } 扩展级别定义它们,但您仍然可以在 JavaCompile 任务级别定义它们。或者在 CompileOptions 上使用新的 release 标志。请参阅docs.gradle.org/current/userguide/…。具体java更新见github.com/gradle/gradle/issues/16628
我如何将工具链用于所有插件?抄送@拉曼
@SouravJha 取决于插件,但我的回答描述了如何使用编译器元数据为插件设置适当的选项。
我的意思是,对于使用 Gradle 作为构建工具的项目,我有 Gradle 包装器,在运行我使用的插件的 Gradle 命令时,应该使用工具链 java 而不是我机器的默认 java。是否有一种为所有插件设置编译器的全局方法。
J
Jafar Karuthedath

如果您遇到来自 Intellij IDE 的问题,请尝试此选项

设置 Gradle JVM Home 在 Project 模块设置中设置 JDK 版本 在 Modules 中检查 JDK 版本


如果您打开终端并运行 gradle build,此解决方案是否仍然有效?还是仅在使用 IDE 运行/编译代码时使用此解决方案?
这是针对 IDE
@Johann 是的。这可以通过 gradle 的某些终端使用来实现:stackoverflow.com/questions/67079327/…
V
Vittal Pai

如果您使用 gradle wrapper 执行,则可以使用 JDK 路径运行命令,如下所示

./gradlew -Dorg.gradle.java.home=/jdk_path_directory


Y
Yekta Sarıoğlu

通过在项目级别 gradle.properties 中指定,您可以轻松地指出您想要的 Java 版本。这将影响当前项目,而不是改变整个系统中每个项目的语言级别。

org.gradle.java.home=<YOUR_JDK_PATH>

没用。 Value 'C:Program FilesJavajdk-11.0.8' given for org.gradle.java.home Gradle property is invalid (Java home supplied is invalid) 请提供示例。
像这样 org.gradle.java.home=C:\\Program Files\\Java\\jdk-11.0.8 转义反斜杠
m
m0j0hn

如果您使用的是 linux 和 gradle 包装器,则可以使用以下解决方案。

将路径添加到 local.properties 文件:

javaHome=<path to JDK>

添加到您的 gradlew 脚本文件:

DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source $DIR/local.properties 2>/dev/null

if ! [ -z "$javaHome" ]
then
  JAVA_HOME=$javaHome
fi

在这个方案中,每个开发者都可以设置自己的 JDK 路径。文件 local.properties 不应包含在版本控制系统中。


遇到与 OP 相同的问题(被迫干涉原始开发人员离开的旧项目),这是迄今为止对我来说最好的解决方案
使用另一个环境变量而不是将其写入 local.properties 文件也可以完成相同的工作。
R
Rosberg Linhares

如果您使用的是 JDK 9+,则可以这样做:

java {
    sourceCompatibility = JavaVersion.VERSION_1_8
    targetCompatibility = JavaVersion.VERSION_1_8
}

tasks.withType<JavaCompile> {
    options.compilerArgs.addAll(arrayOf("--release", "8"))
}

您还可以看到以下相关问题:

Gradle:[Java 9] 为 -release 编译器参数添加便捷方法

Gradle 的 Eclipse 插件:JDK API 兼容性应与 sourceCompatibility 选项匹配。


问题:如果我们已经设置了 target,为什么还需要设置 --release
你救了我的命。
K
Kiran

还有另一种选择。在 Eclipse 中可用的 gradle 任务中,您可以设置所需的 jdk 路径。 (我知道问题发布已经有一段时间了。这个答案可以帮助别人。)

右键单击部署或任何其他任务,然后选择“打开 Gradle 运行配置...”

https://i.stack.imgur.com/AAAQn.png

然后导航到“Java Home”并粘贴所需的 Java 路径。

https://i.stack.imgur.com/CoLUP.png

请注意,bin 将由 gradle 任务本身添加。所以不要将“bin”添加到路径中。


看不到 gradle 任务
这是为 Eclipse 准备的吗?如果是,请在您的回答中说明。
M
Manoj

我在我的 GRADLE_HOME/bin/gradle 文件中添加了这一行 - export JAVA_HOME=/path/to/java/version


S
Sergey Alekhin

对于 Windows 运行带有 jdk 11 路径参数的 gradle 任务

gradlew clean build -Dorg.gradle.java.home="c:/Program Files/Java/jdk-11"

C
Chinese Cat

对于 Windows,打开 cmd 并进入您的项目根目录,然后执行如下命令:

gradlew build -Dorg.gradle.java.home="jdk_path"

我的 JDK 位于此路径:C:\Program Files\Java\jdk-11.0.5。

因此,就我而言,它如下所示:

gradlew build -Dorg.gradle.java.home="C:\Program Files\Java\jdk-11.0.5"

此外,如果您想指定某个变体,您可以这样做:

gradlew assembleDebug -Dorg.gradle.java.home="E:\AndroidStudio\jre"

此命令将使用 Debug 变体编译您的项目,并在 2 个文件夹中输出 2 个 apks(debug + release)。


R
Remo Meier

有一个 Gradle 插件可以自动下载/引导 JDK:

https://plugins.gradle.org/plugin/com.github.rmee.jdk-bootstrap

还没有 IDE 集成,并且在 Windows 上需要一个像样的 shell。


“体面的外壳”基本上意味着 bash。我刚刚提交了一个 PR 以使其也适用于批处理文件。
b
btm me

*gradle.properties
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true
org.gradle.java.home=C\:\\Program Files\\Java\\jdk-11.0.15
-------------------------------------------------------------------
**build.gradle**
android {
    compileSdkVersion flutter.compileSdkVersion
    ndkVersion flutter.ndkVersion
    compileOptions {
        sourceCompatibility 11
        targetCompatibility 11
    }
    kotlinOptions {
        jvmTarget = '11'
        useIR = true
    }
    sourceSets {
        main.java.srcDirs += 'src/main/kotlin'
    }*

在 flutter3.0 和 jdk11 安装后,这些步骤对我有用


带有更新答案的旧问题。太好了+1
P
Paul Verest

Gradle (Eclipse plugin) 所示

https://i.stack.imgur.com/mwzaD.png

http://www.gradle.org/get-started

Gradle 使用它在您的路径中找到的任何 JDK(要检查,请使用 java -version)。或者,您可以将 JAVA_HOME 环境变量设置为指向所需 JDK 的安装目录。

如果您正在使用此 Eclipse 插件或 Enide Studio 2014,要使用的替代 JAVA_HOME(在 Preferences 中设置)将在 0.15 版中,请参阅 http://www.nodeclipse.org/history


嗨,保罗,实际上,这正是我的问题。我想为 gradle-building 任务定义一个不同于 JAVA_HOME 中定义的 JDK。不过,很高兴知道 eclipse 插件中会有一个条目用于此:)
标准 Eclipse 允许为每个启动配置定义环境变量。但这不是我们用 gradle 尝试的。如果您进一步探索此问题,请打开一个问题github.com/Nodeclipse/nodeclipse-1/issues
T
TacB0sS

因此,我将 IntelliJ 用于我的 Android 项目,以下解决了 IDE 中的问题:

只是因为它可能会节省我浪费的几个小时... IntelliJ -> Preferences -> Build, Execution, Deployment -> Build tools -> Maven -> Gradle

并将 Gradle JVM 设置为 1.8 确保您还安装了 JDK 8...

注意:该项目从命令行编译得很好


l
logbasex

有一个非常简单的方法。您可以尝试以下解决方案。

sudo update-alternatives --config java

更新您的 java 版本后,让我们检查 Gradle 当前 JVM 的版本以确保应用了此更改。

gradle -v

有关更多详细信息,请查看您的 gradlew 文件(在类 Unix 操作系统中)或 gradlew.bat 文件(在 Window 操作系统中)以查看 Gradle 配置 JAVACMD 变量的方式。

例如

# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
        # IBM's JDK on AIX uses strange locations for the executables
        JAVACMD="$JAVA_HOME/jre/sh/java"
    else
        JAVACMD="$JAVA_HOME/bin/java"
    fi
    if [ ! -x "$JAVACMD" ] ; then
        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
    fi
else
    JAVACMD="java"
    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi

J
JasonBodnar

如果您只想设置一次以运行特定命令:

JAVA_HOME=/usr/lib/jvm/java-11-oracle/ gw build

这在 Windows cmd.exe 上对我不起作用
B
Braian Coronel

安卓工作室

文件 > 项目结构 > SDK 位置 > JDK 位置 >

/usr/lib/jvm/java-8-openjdk-amd64

总帐

Install JDK


s
sobczak.dev

如果您使用 Kotlin DSL,则在 build.gradle.kts 中添加:

tasks.withType<JavaCompile> {
    options.isFork = true
    options.forkOptions.javaHome = File("C:\\bin\\jdk-13.0.1\\")
}

当然,我假设您有 Windows 操作系统并且 javac 编译器在路径 C:\bin\jdk-13.0.1\bin\javac 中。对于 Linux 操作系统将是类似的。


J
James Graham

我正在使用 Gradle 4.2 。默认的 JDK 是 Java 9。在 Java 9 的早期,Gradle 4.2 在 JDK 8(不是 JDK 9)上正确运行。

我像这样在文件 %GRADLE_HOME%\bin\gradle.bat 中手动设置 JDK:

@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem  Gradle startup script for Windows
@rem
@rem ##########################################################################

@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal

set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%..

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

@rem VyDN-start.
set JAVA_HOME=C:\Program Files\Java\jdk1.8.0_144\
@rem VyDN-end.

set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%


@rem VyDN-start.
set JAVA_HOME=C:\Program Files\Java\jdk1.8.0_144\
@rem VyDN-end.


set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto init

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:init
@rem Get command-line arguments, handling Windows variants

if not "%OS%" == "Windows_NT" goto win9xME_args

:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2

:win9xME_args_slurp
if "x%~1" == "x" goto execute

set CMD_LINE_ARGS=%*

:execute
@rem Setup the command line

set CLASSPATH=%APP_HOME%\lib\gradle-launcher-4.2.jar

@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.launcher.GradleMain %CMD_LINE_ARGS%

:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd

:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1

:mainEnd
if "%OS%"=="Windows_NT" endlocal

:omega

I
IamDOM

感谢 this answer,即使 JAVA_HOME 设置正确,我也能够确定我的问题是 gradle 选择了错误的 JDK。

我原来的评论:

我的操作系统是 Linux,我的 JAVA_HOME 指向正确的路径。我什至用这个命令 gradle build -Dorg.gradle.java.home=$JAVA_HOME 来证明我的观点。我已经在 Ubuntu 中使用 snap 安装了 gradle,我猜它正在使用一些捆绑的 JDK。

我的解决方案:

我已经使用 snap 删除了 gradle,然后我通过下载他们的二进制文件手动安装了 gradle 并将其放入 PATH 中。

我的结论是 Ubuntu 上的 gradle snap 安装与一些较旧的 JDK 捆绑在一起。