How does org.gradle.java.home work, where can you set it, and what are its drawbacks compared to newer mechanisms?
answer
- absolute JDK path
- gradle.properties / -D / ~/.gradle
- non-portable, no provisioning
- fallback = JAVA_HOME launcher
- criteria file replaces it
basics
~10 sorg.gradle.java.home is a Gradle property holding an absolute path to the JDK that should run the daemon. You set it in gradle.properties (or via -D). Its drawback: the path is machine-specific and not portable.
solid answer
~40 s`org.gradle.java.home` is a Gradle build-environment property whose value is an **absolute filesystem path** to a JDK installation. When set, Gradle starts (or matches) its daemon on that JVM instead of the one that launched `gradlew`. You can set it in the project's `gradle.properties`, in the user-level `~/.gradle/gradle.properties`, or pass it as a system property. Because it is a *hardcoded path*, it's inherently **non-portable**: a value like `/Library/Java/.../jdk-17` won't exist on a teammate's Linux box or in CI. It also doesn't trigger any auto-provisioning — the JDK must already be installed there. The modern alternative, **Daemon JVM Criteria** (`gradle/gradle-daemon-jvm.properties`), declares a *version/vendor* instead of a path, so Gradle can locate or download a matching JDK on any machine — making the daemon JVM choice version-controlled and reproducible.
code
bash · 5 lines# One-off override via system property
./gradlew build -Dorg.gradle.java.home=/Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home
# Or in ~/.gradle/gradle.properties (personal, not committed):
# org.gradle.java.home=/Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Homego deeper
Know that it's an absolute path to the JDK that runs Gradle, set in gradle.properties.
Explain its locations, precedence, the JAVA_HOME fallback, and why the path is non-portable.
Contrast with Daemon JVM Criteria; recommend personal-only overrides and criteria for shared config.
Define policy: forbid committed absolute paths; standardize on criteria + provisioned/managed JDKs across teams and CI.
## `org.gradle.java.home` This is one of Gradle's **build-environment properties** (the `org.gradle.*` family read from `gradle.properties`). Its job is narrow but important: it points Gradle at the JDK that should run the **daemon** — the process that executes Gradle itself. ### What its value is An **absolute path** to a JDK home directory, e.g. on macOS `/Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home`. Gradle launches/reuses a daemon on that JVM. ### Where you can set it (precedence high → low) 1. Command line as a system property: `./gradlew build -Dorg.gradle.java.home=/path/to/jdk`. 2. Project `gradle.properties` (committed to the repo) — **discouraged** because paths differ per machine. 3. User home `~/.gradle/gradle.properties` — a reasonable place for a *personal* override. 4. Environment fallback: if unset, Gradle uses the JVM that started `gradlew`, typically derived from `JAVA_HOME`. ### Why it's problematic - **Not portable.** A hardcoded path is valid only on the machine that wrote it. Committing it to project `gradle.properties` breaks other contributors and CI. - **No provisioning.** Unlike toolchains/criteria, it never downloads a JDK; the path must already exist or the daemon fails to start. - **Easy to drift.** When you upgrade your JDK and the old path disappears, builds break with a cryptic 'Java home ... does not exist' error. ### The modern replacement: Daemon JVM Criteria Gradle 8.8+ introduced `gradle/gradle-daemon-jvm.properties` (generated via `./gradlew updateDaemonJvm`). Instead of a path you declare a **version** (and optionally vendor/implementation): ```properties toolchainVersion=17 toolchainVendor=ADOPTIUM ``` Gradle then *discovers* (and, in newer versions, can provision) a matching JDK on whatever machine runs the build. This is version-controlled, portable, and reproducible — everything `org.gradle.java.home` is not. ### When `org.gradle.java.home` is still fine - A *personal* override in `~/.gradle/gradle.properties` for your own machine. - A controlled CI image where the path is guaranteed and stable. For anything shared/committed, prefer the criteria file.
- Why is committing org.gradle.java.home to the project's gradle.properties a bad idea?The absolute path is machine-specific; it won't exist for other developers or in CI, breaking the daemon startup for everyone but the author.
- If org.gradle.java.home is not set, how does Gradle decide which JVM runs the daemon?It falls back to the JVM that launched gradlew — typically the one resolved from JAVA_HOME or the system's java on PATH.
- Does org.gradle.java.home download a JDK if the path is missing?No. It performs no provisioning; if the path doesn't exist the daemon fails to start. Only criteria/toolchains can provision.
saying these in an interview costs you the question
- Saying org.gradle.java.home accepts a version number — it requires an absolute path.
- Claiming it provisions/downloads a JDK automatically.
- Recommending committing it to project gradle.properties as the standard approach.