How do you declare a plugin id for a custom Gradle plugin using the java-gradle-plugin plugin, and what is the role of implementationClass?
answer
- apply java-gradle-plugin
- gradlePlugin { plugins { create … } }
- id + implementationClass
- generates META-INF/gradle-plugins/<id>.properties
- Plugin<Project>.apply called on apply
basics
~20 sApply the java-gradle-plugin plugin, then in the gradlePlugin { plugins { … } } block register a plugin entry with an id and an implementationClass — the fully-qualified name of your Plugin<Project> class that Gradle instantiates when that id is applied.
solid answer
~40 sYou apply the `java-gradle-plugin` plugin to your build-logic project. It exposes the `gradlePlugin` extension where you register named plugin entries: ```kotlin gradlePlugin { plugins { create("greeting") { id = "com.acme.greeting" implementationClass = "com.acme.GreetingPlugin" } } } ``` `id` is the public identifier consumers use in `plugins { id("com.acme.greeting") }`. `implementationClass` is the fully-qualified name of the class implementing `Plugin<Project>` (or `Plugin<Settings>`). When a build applies the id, Gradle reads the descriptor, finds this class and calls its `apply` method. The `java-gradle-plugin` plugin also auto-generates the plugin descriptor file and a plugin marker artifact so the id can be resolved from a repository.
code
kotlin · 12 linesplugins {
`java-gradle-plugin`
}
gradlePlugin {
plugins {
create("greeting") {
id = "com.acme.greeting"
implementationClass = "com.acme.GreetingPlugin"
}
}
}go deeper
Recall that you apply java-gradle-plugin and set id + implementationClass in gradlePlugin { plugins { … } }.
Explain the generated descriptor file and that the entry name differs from the id; show the Kotlin DSL.
Discuss why id and class are decoupled, reverse-DNS naming, and what the descriptor contract means at apply time.
Frame id conventions as an org-wide contract (namespacing, stability across renames) and how that affects internal plugin catalogs.
## What a plugin id is A Gradle plugin needs a stable, public **id** so build scripts can apply it with `plugins { id("...") }`. The id is decoupled from the implementation class name on purpose: the class can move or be renamed without breaking consumers, and one published module can expose several ids. ## The `java-gradle-plugin` plugin Applying `java-gradle-plugin` to a JVM project does three things: 1. Adds the `gradleApi()` dependency to `implementation` so you can compile against Gradle types. 2. Adds the `gradlePlugin` extension (a `GradlePluginDevelopmentExtension`) for declaring plugins. 3. Wires tasks that generate the **plugin descriptor** and **plugin marker** artifacts. ## Declaring a plugin ```kotlin gradlePlugin { plugins { create("greeting") { // the NamedDomainObjectContainer entry name (arbitrary) id = "com.acme.greeting" // public id consumers apply implementationClass = "com.acme.GreetingPlugin" } } } ``` - The container entry name (`"greeting"`) is internal bookkeeping; it is **not** the id. - `id` must be a valid plugin id: lowercase, dot-separated namespaces, typically reverse-DNS to avoid collisions. - `implementationClass` is the fully-qualified class name implementing `Plugin<Project>`. ## The descriptor file From each entry, the `java-gradle-plugin` generates `META-INF/gradle-plugins/<id>.properties` on the classpath containing one line: ``` implementation-class=com.acme.GreetingPlugin ``` This is the actual runtime contract: when a build applies `com.acme.greeting`, Gradle looks up `com/acme/greeting` → wait, it looks up `META-INF/gradle-plugins/com.acme.greeting.properties`, reads `implementation-class`, loads that class and instantiates it. ## Why use the DSL instead of hand-writing the descriptor Before `java-gradle-plugin` you hand-authored the `.properties` file. The DSL is preferred because it also generates **plugin marker artifacts** (needed for `plugins {}` resolution from a repository) and feeds the metadata into validation and publishing tasks.
- What file does java-gradle-plugin generate from a plugin declaration, and what does it contain?A descriptor at META-INF/gradle-plugins/<id>.properties containing a single line implementation-class=<fully-qualified class>. Gradle reads it at apply time to find and instantiate the plugin class.
- Is the name passed to create("greeting") the same as the plugin id?No. That name is just the container entry key for build-logic bookkeeping. The public id is the separate id property you assign inside the block.
saying these in an interview costs you the question
- Confusing the container entry name with the public plugin id.
- Hand-writing the META-INF descriptor when java-gradle-plugin already generates it.
- Claiming implementationClass is the id rather than the FQN of the Plugin<Project> class.