skip to content

How do you declare multiple plugin ids from a single build-logic project, and what gets generated for each?

level: middleimportance: should knowfreq 35%

answer

  1. plugins is a NamedDomainObjectContainer
  2. multiple create("…") entries
  3. one descriptor + one marker per id
  4. single shared implementation jar
  5. ids must be unique

basics

~20 s

Add several create("…") entries inside gradlePlugin { plugins { … } }, each with its own id and implementationClass. Each entry produces its own descriptor file and, when publishing, its own marker artifact, all backed by the same implementation jar.

solid answer

~30 s

The `gradlePlugin.plugins` container is a `NamedDomainObjectContainer`, so you can register as many plugins as you want: ```kotlin gradlePlugin { plugins { create("greeting") { id = "com.acme.greeting" implementationClass = "com.acme.GreetingPlugin" } create("farewell") { id = "com.acme.farewell" implementationClass = "com.acme.FarewellPlugin" } } } ``` For each entry Gradle generates a separate descriptor `META-INF/gradle-plugins/<id>.properties` inside the single implementation jar, and (with `maven-publish`) a separate marker module `<id>:<id>.gradle.plugin:<version>` pointing at that one jar. Consumers can then apply either id independently. This is the standard pattern for a `buildSrc`/`build-logic` module that ships a family of related convention or capability plugins from one codebase.

code

kotlin · 12 lines
kotlin
gradlePlugin {
  plugins {
    create("javaConventions") {
      id = "com.acme.java-conventions"
      implementationClass = "com.acme.JavaConventionsPlugin"
    }
    register("publishing") {   // register = lazy creation
      id = "com.acme.publishing"
      implementationClass = "com.acme.PublishingPlugin"
    }
  }
}

go deeper

for a junior

Know you can add several create("…") entries, each with its own id and class.

for a middle

Explain that one jar backs all ids and each id gets its own descriptor and marker.

for a senior

Discuss the convention-plugin-family pattern, container ergonomics (register vs create), and uniqueness constraints.

for a principal

Decide module granularity and id taxonomy for a large internal plugin suite shared across teams.

## One jar, many ids A single build-logic project routinely exposes a **family** of plugins — e.g. one for Java conventions, one for publishing, one for code quality. Rather than a module per plugin, you register multiple entries in the same `gradlePlugin` block. ```kotlin gradlePlugin { plugins { create("javaConventions") { id = "com.acme.java-conventions" implementationClass = "com.acme.JavaConventionsPlugin" } create("publishing") { id = "com.acme.publishing" implementationClass = "com.acme.PublishingPlugin" } } } ``` ## What is generated per entry For **each** declared plugin: 1. A descriptor `META-INF/gradle-plugins/<id>.properties` with `implementation-class=<FQN>` — all packaged in the **same** implementation jar. 2. When `maven-publish` is applied, a dedicated marker publication `<name>PluginMarkerMaven` producing `<id>:<id>.gradle.plugin:<version>`. The implementation jar (`group:name:version`) is published once; every marker depends on it. ## Why this is the standard pattern - **DRY**: shared helper classes, a `Provider`/`Property`-based config model, and test infrastructure live in one place. - **Independent application**: consumers apply only the ids they need; ids are decoupled, so adding a new id is non-breaking. - **Cohesion**: convention plugins for a stack are versioned and released together. ## NamedDomainObjectContainer ergonomics Because `plugins` is a `NamedDomainObjectContainer<PluginDeclaration>`, you can also use `register("…")` for lazy creation, iterate to apply common settings, or reference an entry by name later. In Kotlin DSL, the type-safe accessors let you write `val greeting by plugins.creating { … }` patterns. The container name (e.g. `"greeting"`) remains internal — only `id` is public. ## Pitfalls - Two entries with the **same id** is an error — ids must be unique within the build. - Pointing two ids at the **same** implementationClass is legal but unusual; usually each id maps to a distinct class. - Forgetting `maven-publish` means descriptors exist but no markers are published, so `plugins {}` resolution from a repo fails.

  • If a project declares three plugin ids, how many implementation jars and how many markers are published?
    One implementation jar (shared) and three markers — one per id, each depending on the single jar.
  • Can two declared ids share the same implementationClass?
    Yes, it is legal — both descriptors point at the same class — though it is unusual; each id normally maps to its own Plugin<Project>.

saying these in an interview costs you the question

  • Assuming you need a separate Gradle project/jar per plugin id.
  • Declaring two entries with the same id (resolution/build error).
  • Saying each id gets its own implementation jar.

context