How do you declare a plugin and its version in the plugins {} block, and where does Gradle resolve that plugin from?
answer
- id + version literal
- marker artifact lookup
- pluginManagement repositories
- Plugin Portal default
- core plugins take no version
basics
~10 sUse id("com.example.foo") version "1.2.3" inside plugins {}. Gradle resolves the plugin from the Gradle Plugin Portal (or repositories declared in settings' pluginManagement) by looking up its marker artifact.
solid answer
~40 sInside the `plugins {}` block you write `id("com.example.foo") version "1.2.3"` (Kotlin DSL) or `id 'com.example.foo' version '1.2.3'` (Groovy). The `id` is the plugin's globally unique identifier; `version` pins which release to fetch. Gradle resolves it by requesting a *plugin marker artifact* (`com.example.foo:com.example.foo.gradle.plugin:1.2.3`) whose POM points at the real implementation jar. Resolution sources are configured in `settings.gradle(.kts)` under `pluginManagement { repositories { ... } }`, which defaults to the Gradle Plugin Portal plus `gradlePluginPortal()`. Core Gradle plugins like `java` or `application` are bundled with the distribution, so they take no version. For third-party plugins the version is mandatory unless it was already resolved elsewhere (e.g. the root project or a version catalog).
code
kotlin · 14 lines// build.gradle.kts
plugins {
id("java") // core, no version
id("org.springframework.boot") version "3.3.0" // third-party, version required
kotlin("jvm") version "2.0.0"
}
// settings.gradle.kts
pluginManagement {
repositories {
gradlePluginPortal()
mavenCentral()
}
}go deeper
Know the id("x") version "y" syntax and that the Plugin Portal is the default source.
Explain the marker-artifact lookup and that repositories come from settings' pluginManagement.
Discuss core-vs-third-party versioning rules and why versions must be literals in the block.
Frame centralizing plugin versions (pluginManagement/catalog) as a governance lever across many repos.
## What the version does The `plugins {}` block is the modern, declarative way to apply Gradle plugins. Each entry has an **id** (a reverse-DNS string like `org.springframework.boot`) and optionally a **version**. The version tells Gradle *which release* of the plugin to download and put on the build script classpath. ```kotlin plugins { id("org.springframework.boot") version "3.3.0" kotlin("jvm") version "2.0.0" // sugar for id("org.jetbrains.kotlin.jvm") } ``` ## Where Gradle resolves it from When you give an id + version, Gradle looks up a **plugin marker artifact**. For id `foo.bar` it requests `foo.bar:foo.bar.gradle.plugin:<version>`. That tiny artifact's POM declares a dependency on the actual implementation jar. This indirection lets the plugin author rename/relocate the implementation without changing the id you type. The **repositories** searched come from `settings.gradle.kts`: ```kotlin pluginManagement { repositories { gradlePluginPortal() // default mavenCentral() google() } } ``` If you declare no `pluginManagement.repositories`, Gradle defaults to the **Gradle Plugin Portal**. ## Core vs third-party - **Core plugins** (`java`, `java-library`, `application`, `jacoco`, ...) ship inside the Gradle distribution. You apply them with `id("java")` and **no version** — versioning them is an error. - **Community/third-party plugins** require a version (in the block, in the catalog, or already resolved by a parent — see follow-ups). ## Constraints of the plugins {} block The block is evaluated very early, before the rest of the script. Versions must be **literal strings** — you cannot compute them from variables or `project.property(...)` directly inside `plugins {}`. To keep versions out of build scripts, use `pluginManagement.plugins {}` in settings or a **version catalog** (`alias(libs.plugins.x)`).
- What is a plugin marker artifact and why does it exist?A small published artifact `id:id.gradle.plugin:version` whose only job is to redirect to the real implementation jar via its POM dependencies. It decouples the stable plugin id from the implementation coordinates, so authors can relocate or rename the implementation without breaking consumers.
- Can you use a variable for the version string inside plugins {}?No — the block is parsed specially and early, so versions must be literal strings (or come from a version catalog/pluginManagement). Computing them with a Groovy/Kotlin expression in the block is not allowed.
saying these in an interview costs you the question
- Claiming every plugin needs a version (core plugins must NOT be versioned).
- Saying plugins resolve from mavenCentral/jcenter by default — the default is the Gradle Plugin Portal.
- Thinking the version string can be a build variable inside the plugins {} block.