skip to content

Why and how would you disable auto-detection with org.gradle.java.installations.auto-detect=false?

level: seniorimportance: should knowfreq 35%

answer

  1. false = stop scanning managers/OS dirs
  2. only paths/fromEnv + launching JVM remain
  3. determinism + speed + hermeticity
  4. auto-detect != auto-download
  5. hardened combo: detect off + download off + fromEnv

basics

~10 s

Set org.gradle.java.installations.auto-detect=false to stop Gradle scanning managers and OS dirs. You then supply JDKs only via installations.paths/fromEnv. It's used on locked-down CI to make the JDK set deterministic and the build fast.

solid answer

~50 s

`org.gradle.java.installations.auto-detect=false` turns off the automatic scanning of SDKMAN, asdf, Homebrew, OS directories, etc. After disabling it, Gradle only considers JDKs you provide explicitly through `org.gradle.java.installations.paths` and `org.gradle.java.installations.fromEnv` (plus the JVM running Gradle). Reasons to disable: - **Determinism**: on a shared or CI machine, scanning might find an unexpected JDK and silently satisfy a toolchain with the wrong build, hurting reproducibility. Explicit lists make the candidate set exact. - **Performance**: probing many discovered installations adds startup cost; pruning to a known few speeds configuration, especially in containers with several JDKs. - **Hermetic/sandboxed builds**: locked-down environments forbid wandering the filesystem; you want only declared, audited JDKs. Note `auto-detect` controls *discovery of installed JDKs*; it does **not** by itself control *downloading* — auto-provisioning is governed separately by `org.gradle.java.installations.auto-download`. A common hardened combo is `auto-detect=false` + `auto-download=false` + explicit `fromEnv`, so the build uses exactly the JDKs the CI image injected and nothing else.

code

bash · 5 lines
bash
# Hermetic CI invocation: only the injected JDKs, no scanning, no downloads
./gradlew build \
  -Dorg.gradle.java.installations.auto-detect=false \
  -Dorg.gradle.java.installations.auto-download=false \
  -Dorg.gradle.java.installations.fromEnv=JDK17,JDK21

go deeper

for a junior

Know the flag exists and that false stops the automatic scanning.

for a middle

Explain what's lost (manager/OS scanning) and what still works (paths/fromEnv/launching JVM).

for a senior

Justify it for CI determinism/speed/hermeticity and pair it correctly with auto-download.

for a principal

Define org-wide policy: detection on for dev ergonomics, off + explicit allowlist on CI, governed via agent-level properties.

## What the flag controls `org.gradle.java.installations.auto-detect` (default `true`) governs whether Gradle runs its **installation suppliers** — the routines that scan SDKMAN, asdf, Jabba, Homebrew, and standard OS JDK directories. Set it to `false` and those suppliers are skipped. Gradle then knows about only: - the JVM that launched Gradle (always considered), and - JDKs you list via `org.gradle.java.installations.paths` and `...fromEnv`. ## Why disable it ### Reproducibility / determinism On a developer laptop or a fat CI image there may be five JDKs lying around. Auto-detection could match a toolchain to whichever one happens to be present, so two machines "satisfy" the same spec with *different* builds (different patch versions or vendors). Disabling detection and enumerating an exact list removes that nondeterminism — the candidate set is whatever you declared, full stop. ### Performance Every discovered installation is probed (a subprocess to read version/vendor). Dozens of installations = measurable configuration-time overhead. Trimming to the few you actually need speeds up the build, which matters in short-lived CI containers. ### Hermeticity / security Sandboxed or audited build environments may disallow scanning arbitrary filesystem locations. An explicit allowlist of audited JDKs is easier to reason about and review. ## How to configure ```properties # gradle.properties org.gradle.java.installations.auto-detect=false org.gradle.java.installations.auto-download=false # also forbid provisioning org.gradle.java.installations.fromEnv=JDK17,JDK21 # the only JDKs allowed ``` ## Don't confuse the two flags | Property | Controls | Default | |---|---|---| | `auto-detect` | scanning the machine for *installed* JDKs | `true` | | `auto-download` | *downloading* a JDK when none matches (provisioning) | `true` | Disabling detection alone does **not** stop downloads; if a spec can't be met from your explicit list, Gradle may still try to provision. The fully-locked configuration disables both and relies on `fromEnv`. ## Failure mode With detection off and no explicit JDK matching a declared toolchain (and downloads off), the build fails with a clear "No compatible toolchains found" error — which is the *intended* hermetic behavior: fail loudly rather than silently use the wrong JDK. Diagnose with `./gradlew javaToolchains`, which under `auto-detect=false` lists only the explicit set. ## When NOT to disable On developer machines, detection is a big convenience — it lets contributors build with whatever JDK their version manager installed. Reserve `auto-detect=false` for CI and locked environments, typically via `~/.gradle/gradle.properties` on the agent or a `-D` flag, not the committed project file (so local devs keep the convenience).

  • Does auto-detect=false also stop Gradle from downloading a JDK?
    No. Downloading is auto-provisioning, controlled by org.gradle.java.installations.auto-download. To fully lock things down you disable both flags.
  • Where should you put auto-detect=false so local developers aren't inconvenienced?
    In the CI agent's ~/.gradle/gradle.properties or as a -D flag in the pipeline, not in the committed project gradle.properties — local devs keep the convenience of scanning their version manager.
  • What error appears if no JDK matches under a fully locked config?
    'No compatible toolchains found' (or similar), which is the intended fail-loud behavior; ./gradlew javaToolchains then shows only the explicit installations.

saying these in an interview costs you the question

  • Claiming auto-detect=false prevents JDK downloads (that's auto-download).
  • Putting auto-detect=false in committed project config, breaking every contributor's local build convenience.
  • Disabling detection but forgetting to supply paths/fromEnv, so no JDK is available at all.

context