What must the in-development plugin build declare so that a consumer including it can apply the plugin by its id?
answer
- apply java-gradle-plugin
- gradlePlugin { plugins { register } }
- id + implementationClass
- generates plugin marker
- no marker = no resolve
basics
~10 sThe plugin build must apply the java-gradle-plugin plugin and declare the plugin id and implementationClass in a gradlePlugin { plugins { register(...) } } block. That generates the marker the consumer's id resolves against.
solid answer
~30 sFor an included build's plugin to be applicable by id, the plugin build needs the `java-gradle-plugin` plugin applied and a `gradlePlugin {}` block declaring each plugin's `id` and `implementationClass`. `java-gradle-plugin` generates the **plugin marker** (`<id>:<id>.gradle.plugin`) and descriptor metadata. When the consumer writes `plugins { id("com.example.myplugin") }` and includes the build, Gradle substitutes that requested marker with the included build's output. Without the `gradlePlugin` declaration (or precompiled-script-plugin auto-detection), there's no marker to match, so the id won't resolve even though the build is included. So the two requirements are: apply `java-gradle-plugin`, and declare the id → implementationClass mapping.
code
kotlin · 11 lines// build-logic/build.gradle.kts
plugins { `java-gradle-plugin` }
gradlePlugin {
plugins {
register("myplugin") {
id = "com.example.myplugin"
implementationClass = "com.example.MyPlugin"
}
}
}go deeper
Know you apply java-gradle-plugin and declare id + implementationClass so the consumer can apply the plugin by id.
Explain that this generates the plugin marker that includeBuild substitution matches against.
Contrast hand-written gradlePlugin declarations with precompiled-script-plugin auto-detection and the shared marker requirement.
Discuss conventions for declaring and versioning plugin ids across a shared build-logic build.
## What 'apply by id' needs under the hood Applying a plugin via `plugins { id("com.example.myplugin") }` makes Gradle look for a **plugin marker artifact**: a tiny module whose coordinates are `com.example.myplugin:com.example.myplugin.gradle.plugin`, which points at the real plugin implementation module. For a published plugin, the build that produces it generates this marker. For an included build to satisfy the id, it must produce that same marker. ## The two requirements in the plugin build 1. **Apply `java-gradle-plugin`.** This plugin: - puts `gradleApi()` on the compile classpath, - validates plugin metadata, - and **generates the plugin marker publication** + the `META-INF` plugin descriptor. 2. **Declare the plugin(s):** ```kotlin plugins { `java-gradle-plugin` } gradlePlugin { plugins { register("myplugin") { id = "com.example.myplugin" implementationClass = "com.example.MyPlugin" } } } ``` The `id` is what consumers type; `implementationClass` is the fully-qualified `Plugin<Project>` (or `Plugin<Settings>`) class. ## How it ties to includeBuild With those in place and `includeBuild("build-logic")` in the consumer settings, Gradle matches the consumer's requested marker to the included build's generated marker and substitutes the locally built plugin — no repository, no publish. ## Alternative: precompiled script plugins If the plugin build uses `kotlin-dsl` / `groovy-gradle-plugin` with files like `src/main/kotlin/com.example.myconvention.gradle.kts`, Gradle auto-derives the id from the file name and auto-generates the marker — you don't hand-write the `gradlePlugin { register }` block for those. The underlying requirement (a marker to substitute) is the same. ## Failure mode If you include the build but forget `java-gradle-plugin` or the id declaration, the consumer's `plugins { id(...) }` fails to resolve — the build is included, but there's no marker to match.
- What does the java-gradle-plugin plugin generate that makes id-based resolution work?It generates the plugin marker publication (`<id>:<id>.gradle.plugin`) and the plugin descriptor metadata. The marker is the coordinate Gradle matches when a consumer requests the id, so the included build can substitute its output for it.
- How is this different when using precompiled script plugins (kotlin-dsl)?With kotlin-dsl / groovy-gradle-plugin, a file like `com.example.foo.gradle.kts` auto-derives its id from the filename and auto-generates the marker, so you don't hand-write the gradlePlugin register block. The requirement — a generated marker to substitute — is identical.
saying these in an interview costs you the question
- Saying just including the build is enough without declaring the id/marker.
- Forgetting that java-gradle-plugin (or kotlin-dsl) is what creates the marker.
- Confusing implementationClass with the plugin id.