Can a single plugin jar expose several plugin ids, and if so how do markers and descriptors handle that? What does this mean for how consumers apply it?
answer
- id is the unit, jar is a container
- one descriptor per id in META-INF/gradle-plugins
- one marker module per id, all → same impl jar
- consumers apply each id; jar downloaded once
- bundled ids version together
basics
~10 sYes. One jar can register many ids — each gets its own META-INF/gradle-plugins/<id>.properties descriptor and, on publish, its own marker module, all depending on the same implementation jar. Consumers apply whichever id they need.
solid answer
~40 sA jar is just a container; the unit that matters is the **plugin id**, declared in the `gradlePlugin { plugins { … } }` block. You can declare several `create(...)` entries in one project, each with its own `id` and `implementationClass`. At build time Gradle writes one descriptor per id — `META-INF/gradle-plugins/<id>.properties` — into the same jar. At publish time, with `maven-publish`, Gradle generates **one marker module per id** (`<id>:<id>.gradle.plugin`), and **all those markers depend on the single implementation jar**. So consumers `id("com.acme.base")` and `id("com.acme.app")` each resolve a distinct marker, but both pull the same implementation jar — Gradle's dependency resolution dedups it. This pattern underpins convention-plugin suites (a 'base' + several focused plugins sharing code). Each id is independently applicable, versioned together since they ship in one jar.
code
kotlin · 14 linesgradlePlugin {
plugins {
create("base") {
id = "com.acme.base"
implementationClass = "com.acme.BasePlugin"
}
create("app") {
id = "com.acme.app"
implementationClass = "com.acme.AppPlugin"
}
}
}
// Publishing emits markers com.acme.base.gradle.plugin and
// com.acme.app.gradle.plugin, both depending on the single impl jar.go deeper
Know that one jar can provide several plugin ids.
Explain per-id descriptors and that each id gets its own marker pointing at the shared jar.
Discuss the dedup-to-one-download behavior and the bundle-vs-split versioning trade-off for convention plugin suites.
Define an org strategy for grouping convention plugins into jars: cohesion, release cadence, and id namespacing across a platform.
## Ids, not jars, are the unit Gradle resolves and applies by **id**. A jar simply carries one or more ids. The mapping lives in per-id descriptors and (for external distribution) per-id marker modules. ## Declaring multiple ids Using the `java-gradle-plugin`'s `gradlePlugin` extension: ```kotlin plugins { `java-gradle-plugin` `maven-publish` } gradlePlugin { plugins { create("base") { id = "com.acme.base" implementationClass = "com.acme.BasePlugin" } create("app") { id = "com.acme.app" implementationClass = "com.acme.AppPlugin" } } } ``` ## What lands in the jar Gradle generates **two** descriptors into the one jar: ``` META-INF/gradle-plugins/com.acme.base.properties → implementation-class=com.acme.BasePlugin META-INF/gradle-plugins/com.acme.app.properties → implementation-class=com.acme.AppPlugin ``` ## What gets published With `maven-publish`, publishing produces: - the **implementation module** `com.acme:acme-plugins:1.0` (the jar with both descriptors), and - **two marker modules**: `com.acme.base:com.acme.base.gradle.plugin:1.0` and `com.acme.app:com.acme.app.gradle.plugin:1.0`. Both markers declare a single dependency on `com.acme:acme-plugins:1.0`. So whichever id a consumer requests, resolution funnels to the same jar. ## Consumer experience ```kotlin plugins { id("com.acme.base") version "1.0" id("com.acme.app") version "1.0" // same jar, resolved once } ``` Gradle resolves each marker, sees both depend on `acme-plugins:1.0`, and downloads that jar exactly once (dependency dedup). Both plugins are then applicable. Because they share a jar, they are **versioned and released together** — a consequence to weigh when deciding whether to split ids across jars or keep them bundled. ## Design implications - **Bundling** several ids in one jar keeps cohesive convention plugins in lockstep and simplifies version management. - **Splitting** ids across jars lets them version independently at the cost of more modules to publish. - This is exactly how internal **convention-plugin** projects ship a family of `base` + feature plugins.
- If two ids from one jar are applied, how many times is the implementation jar downloaded?Once. Both markers depend on the same implementation module; Gradle's dependency resolution dedups it to a single download/classpath entry.
- What's a downside of bundling several ids in one jar?They are versioned and released together — you can't bump one id's version without re-releasing the whole jar. Splitting into separate jars enables independent versioning at the cost of more modules.
saying these in an interview costs you the question
- Saying each id needs its own jar — multiple ids commonly share one jar.
- Claiming applying two ids from one jar downloads the jar twice — resolution dedups to one.
- Believing the marker contains code, so multiple ids 'duplicate' code — markers are empty redirects.