skip to content

When would you use `JvmVendorSpec.matching("...")` instead of a named vendor constant, and what are the trade-offs?

level: middleimportance: should knowfreq 22%

answer

  1. JvmVendorSpec.matching("...")
  2. substring match on vendor metadata
  3. use when no named constant exists
  4. constants encode aliases / more robust
  5. best for local detection, not provisioning

basics

~10 s

JvmVendorSpec.matching("string") matches any JDK whose vendor metadata contains that substring. Use it for a distribution with no named constant. The trade-off: it's free-text, so a too-loose string can match unintended JDKs.

solid answer

~50 s

`JvmVendorSpec` provides named constants (`ADOPTIUM`, `AZUL`, `AMAZON`, …) plus a generic `matching(String)` factory. `matching` does a **substring match against the vendor string** Gradle reads from each JDK's metadata (its `release`/`java.vendor`). You reach for it when: - the distribution has no dedicated constant, or - you need to match an internal/enterprise rebuild with a custom vendor name. ```kotlin java { toolchain { languageVersion = JavaLanguageVersion.of(21) vendor = JvmVendorSpec.matching("AdoptOpenJDK") } } ``` Trade-offs: named constants encode the known aliases a vendor uses and play nicely with provisioning resolvers, so they're more robust. `matching` is free-text — too broad and it accepts JDKs you didn't intend; too specific and it misses valid ones whose string differs slightly. Provisioning support also depends on the resolver recognising the string, so `matching` is most reliable for **local detection** of already-installed JDKs.

code

kotlin · 6 lines
kotlin
java {
  toolchain {
    languageVersion = JavaLanguageVersion.of(21)
    vendor = JvmVendorSpec.matching("AdoptOpenJDK")
  }
}

go deeper

for a junior

Know that named constants exist and that matching("...") is the escape hatch for unlisted vendors.

for a middle

Explain substring matching against vendor metadata and the over/under-match risk; prefer constants.

for a senior

Discuss provisioning limitations of arbitrary strings and choosing a stable, distinctive fragment.

for a principal

Standardise vendor selection in shared build logic; avoid scattering brittle matching strings across modules.

## Named constants vs. `matching` `JvmVendorSpec` is the type of the toolchain `vendor` constraint. It comes in two flavours: 1. **Named constants** — `JvmVendorSpec.ADOPTIUM`, `AZUL`, `AMAZON`, `BELLSOFT`, `GRAAL_VM`, `IBM`, `ORACLE`, `MICROSOFT`, `SAP`, etc. Each constant knows the **set of vendor strings/aliases** that distribution historically uses, so it matches robustly even when a vendor renames itself (e.g. AdoptOpenJDK → Adoptium/Temurin). 2. **`JvmVendorSpec.matching(String)`** — builds a spec that matches a JDK when the supplied string appears (as a substring, case-insensitively) in the JDK's vendor metadata. ## How matching works For every candidate JDK, Gradle reads a vendor identifier from the installation's metadata (the `release` file / `java.vendor`). A named constant compares it against its known aliases; `matching("x")` simply checks whether `"x"` is contained in that identifier. ```kotlin java { toolchain { languageVersion = JavaLanguageVersion.of(21) // No constant for this internal rebuild: vendor = JvmVendorSpec.matching("AcmeCorp JDK") } } ``` ## Trade-offs and pitfalls - **Robustness:** a constant tracks alias changes for you; a hard-coded string does not. Prefer the constant when one exists. - **Over/under-matching:** `matching("Open")` is dangerously broad; `matching("Eclipse Adoptium Temurin-21.0.3+9")` is needlessly brittle. Choose a stable, distinctive fragment. - **Provisioning:** the Foojay resolver maps **known** vendors to downloads. An arbitrary `matching` string may have no provisioning mapping, so it works best for selecting **already-installed** JDKs (local detection) rather than triggering a download. ## Practical guidance Default to a named constant. Use `matching` only for distributions Gradle doesn't model or for enterprise rebuilds, and pick the most stable, unambiguous substring you can.

  • Why prefer `JvmVendorSpec.ADOPTIUM` over `matching("Adoptium")`?
    The constant encodes all known aliases the distribution has used (e.g. AdoptOpenJDK, Eclipse Temurin) and is recognised by provisioning resolvers, so it matches more robustly than a single hard-coded substring.
  • Does `matching` reliably trigger auto-provisioning?
    Not necessarily — provisioning resolvers map known vendors to downloads, so an arbitrary string may have no mapping; `matching` is most dependable for detecting already-installed JDKs.

saying these in an interview costs you the question

  • Claiming `matching` does an exact equality check — it is a (case-insensitive) substring match.
  • Using a very short/common substring that accidentally matches multiple distributions.

context