A teammate's build fails with 'No compatible toolchains found' even though they have the right JDK installed. How do you debug the detection?
answer
- ./gradlew javaToolchains first
- Options block = detect/download on?
- not listed -> non-scanned path or detect off
- listed but unused -> vendor/version/arch mismatch
- stale daemon -> --stop and re-probe
basics
~10 sRun ./gradlew javaToolchains to see what Gradle actually discovered. If the JDK isn't listed, it's in a non-scanned location or detection is off — add it via installations.paths/fromEnv or re-enable auto-detect.
solid answer
~50 sStart with the diagnostic: `./gradlew -q javaToolchains` prints every JDK Gradle found, its version, vendor, architecture, and detection source. Walk through likely causes: 1. **JDK not in a scanned location** — it's a hand-extracted tarball under a custom path. Fix: list it in `org.gradle.java.installations.paths` or export+`fromEnv`. 2. **Detection disabled** — `org.gradle.java.installations.auto-detect=false` in a `gradle.properties` (often `~/.gradle`). Re-enable or add explicit paths. 3. **Architecture mismatch** — an x64 JDK on Apple Silicon won't satisfy a native toolchain request; the report shows arch. 4. **Vendor/version too strict** — the toolchain spec asks for a vendor the installed JDK isn't; loosen the spec or install/declare the matching vendor. 5. **Stale probe cache or pointing at a JRE/bin dir** — re-run; ensure the path is the JDK *home* root, not `bin/`. The report's "source" column tells you whether Gradle saw it via a manager, env var, configured path, or the current JVM — that pinpoints which supplier failed.
code
bash · 3 lines./gradlew -q javaToolchains # what did Gradle discover?
./gradlew --stop # clear stale daemon probe cache
./gradlew build --info 2>&1 | grep -i toolchain # why each JDK was rejectedgo deeper
Know to run ./gradlew javaToolchains to see discovered JDKs.
Read the report's Options + Vendor/Version/Arch columns and map each failure to a fix.
Distinguish 'not discovered' vs 'discovered but rejected' and use --info for rejection reasons.
Turn recurring 'works on my machine' detection failures into a standardized env-var/JDK-layout contract across the team's machines and CI.
## First move: the `javaToolchains` report Never guess — ask Gradle what it sees: ```bash ./gradlew -q javaToolchains ``` Sample output: ``` + Options | Auto-detection: Enabled | Auto-download: Enabled + Eclipse Temurin JDK 17.0.9+9 | Location: /Users/x/.sdkman/candidates/java/17.0.9-tem | Language Version: 17 | Vendor: Eclipse Temurin | Architecture: aarch64 | Detected by: SDKMAN! ``` The **Options** block tells you immediately whether auto-detect and auto-download are on. Each entry shows **Language Version**, **Vendor**, **Architecture**, and **Detected by** (the supplier). ## Decision tree ### 1. JDK absent from the list entirely Gradle never discovered it. Either: - It's in a non-scanned location (custom `/opt`, NFS). → add `org.gradle.java.installations.paths=/opt/jdk-17` or export a var and use `fromEnv`. - Auto-detection is off. The Options block will read `Auto-detection: Disabled`. → re-enable, or add explicit paths. - The path points at a JRE or at `.../bin` instead of the JDK home root. → fix the path. ### 2. JDK present but not selected The spec is stricter than the install: - **Vendor mismatch** — spec asks `vendor = GRAAL_VM` but you have Temurin. The report's Vendor column reveals it. - **Version mismatch** — spec asks `languageVersion = 21`, you have 17. - **Architecture mismatch** — `Architecture: x86_64` under Rosetta when an aarch64 toolchain is needed. Fix by aligning the spec or installing/declaring the matching JDK. ### 3. It works for you but not a teammate Differences are environmental: - Their `~/.gradle/gradle.properties` disables detection or lacks the `fromEnv` var your CI assumes. - Their version manager installed the JDK somewhere yours didn't. - They never exported the env var your `fromEnv` references. Have them run the same `javaToolchains` report and diff the Options + discovered set. ## Probe cache gotcha Gradle caches probe results. If you just installed a JDK mid-session, a stale daemon may not see it. `./gradlew --stop` then re-run, or simply re-invoke — a fresh configuration re-probes. ## Useful extra signal `--info` logging around toolchain resolution prints which installations were considered and why each was rejected, which is the deepest signal when the report alone isn't conclusive. ## Summary checklist 1. `./gradlew javaToolchains` — is the JDK listed? 2. Options block — is auto-detection enabled? 3. If listed: compare Vendor / Version / Architecture against the spec. 4. If not listed: add via `paths`/`fromEnv`, fix the home path, or re-enable detection. 5. Restart the daemon if you installed the JDK after the daemon started.
- The JDK shows in javaToolchains but the toolchain still won't resolve. What now?Compare the report's Vendor, Language Version, and Architecture columns against the declared toolchain spec — a vendor or arch mismatch is the usual culprit. --info logging shows the rejection reason.
- Why might it work on your machine but not a teammate's with the same JDK installed?Environmental differences: their ~/.gradle/gradle.properties may disable detection, a fromEnv variable may be unset for them, or their version manager installed the JDK in a location yours scanned but theirs doesn't expose.
- You installed a JDK but Gradle still doesn't see it. Quick fix?Stop the daemon (./gradlew --stop) so the next run re-probes installations; the running daemon may hold a stale probe cache.
saying these in an interview costs you the question
- Editing build logic before running javaToolchains to see what Gradle actually discovered.
- Assuming JAVA_HOME being set guarantees the toolchain resolves — the spec drives selection.
- Ignoring the Architecture column on Apple Silicon / Rosetta mismatches.