skip to content

A developer sets `vendor = JvmVendorSpec.AZUL` but only Temurin is installed and provisioning is disabled. What happens, and how would you diagnose it?

level: seniorimportance: should knowfreq 26%

answer

  1. no match -> build fails, no silent fallback
  2. ./gradlew javaToolchains report
  3. detection then provisioning
  4. auto-download flag + Foojay resolver
  5. fix: install+paths, enable provisioning, or relax spec

basics

~10 s

Toolchain resolution finds no Azul JDK; with provisioning off it can't download one, so the build fails with a 'No matching toolchain' error. Diagnose with ./gradlew javaToolchains to list detected JDKs and their vendors.

solid answer

~40 s

Adding `vendor` ANDs a constraint onto the spec. Resolution first does **local detection**: Gradle enumerates installed JDKs and keeps only Azul ones — here, none. It then tries **auto-provisioning**, but that's disabled (`org.gradle.java.installations.auto-download=false` or no resolver plugin), so it cannot download Azul. The build fails fast: *"No matching toolchains found for the requested specification"*, listing the requested version/vendor. To diagnose, run: ```bash ./gradlew javaToolchains ``` This prints every JDK Gradle detected, where it found it, and its **vendor** — making it obvious that only Temurin is present. The fix is one of: install an Azul JDK and point Gradle at it (`org.gradle.java.installations.paths`), re-enable provisioning + the Foojay resolver, or relax the spec (drop the vendor or switch to ADOPTIUM). The key point: Gradle never silently substitutes a different vendor — that's intentional for reproducibility.

code

bash · 2 lines
bash
./gradlew javaToolchains
# Lists detected JDKs, their vendors, and whether auto-download is enabled

go deeper

for a junior

Know that an unmatched vendor causes a build failure, not a silent fallback.

for a middle

Walk through detect-then-provision and name ./gradlew javaToolchains as the diagnostic.

for a senior

Explain the exact failure, the role of auto-download + resolver, and enumerate the fix options with their trade-offs.

for a principal

Design CI/dev-machine provisioning policy so pinned vendors resolve reliably without per-developer manual setup.

## Resolution model recap When a task needs a toolchain, Gradle resolves the `JavaToolchainSpec` (version + optional vendor + optional implementation) in two phases: 1. **Local detection** — discover installed JDKs from: the JDK running Gradle, common OS install dirs, `JAVA_HOME`/`*_JDK` env vars (when `org.gradle.java.installations.fromEnv` lists them), explicit `org.gradle.java.installations.paths`, and SDK managers. Each candidate is filtered by version, then vendor, then implementation. 2. **Auto-provisioning** — if nothing matched and `org.gradle.java.installations.auto-download` is not `false` AND a provisioning resolver (e.g. the Foojay Disco plugin) is applied, Gradle downloads a matching JDK. ## This scenario - Detection finds only Temurin → filtered out by `vendor = AZUL` → empty set. - Provisioning disabled → cannot fetch Azul. - Result: **build failure** with a message like *"No matching toolchains found for the requested specification: {languageVersion=21, vendor=AZUL, implementation=vendor-specific}"*. Gradle does **not** fall back to Temurin — silent substitution would defeat the purpose of pinning a vendor. ## Diagnosing The canonical tool is the built-in report task: ```bash ./gradlew javaToolchains ``` Sample output sketch: ``` + Options | Auto-detection: Enabled | Auto-download: Disabled + Eclipse Temurin JDK 21.0.3+9 | Location: /Library/Java/.../Home | Language Version: 21 | Vendor: Eclipse Temurin | Detected by: Common Linux Locations ``` Seeing *Auto-download: Disabled* and only Temurin entries explains both the failure and the cause. ## Fixes (pick one) - **Install Azul** and expose it via `org.gradle.java.installations.paths=/path/to/zulu` (in `gradle.properties` or `-P`/`-D`). - **Enable provisioning:** apply the Foojay resolver in `settings.gradle(.kts)` and set `org.gradle.java.installations.auto-download=true` (the default), letting Gradle download Azul. - **Relax the spec:** drop `vendor`, or change it to a vendor that is available, if the distribution genuinely doesn't matter. ## Takeaway Vendor constraints are strict by design. The failure is a feature; `javaToolchains` is the first stop, and the resolver/provisioning config is the lever to satisfy the constraint without weakening reproducibility.

  • Why doesn't Gradle just use the installed Temurin JDK instead of failing?
    Because the vendor was explicitly pinned; silently substituting another vendor would undermine the reproducibility guarantee the constraint exists to provide, so Gradle fails fast instead.
  • Which task or flags help you see what JDKs Gradle can see?
    `./gradlew javaToolchains` lists detected installations with vendor and detection source; `-Porg.gradle.java.installations.paths=...` and the `fromEnv` property control which extra ones are discovered.
  • How would you enable provisioning to fix it without changing the spec?
    Apply the Foojay Disco resolver plugin in settings and ensure `org.gradle.java.installations.auto-download` is not false, so Gradle downloads the requested Azul JDK.

saying these in an interview costs you the question

  • Saying Gradle falls back to any available JDK — it fails when the vendor can't be matched.
  • Confusing the Gradle JVM with the toolchain JVM when reasoning about which JDK is missing.
  • Forgetting that provisioning needs BOTH a resolver plugin and auto-download enabled.

context