How do you set the groupId, artifactId, and version on a MavenPublication, and how does that relate to project.group and project.version?
answer
- groupId / artifactId / version
- defaults: project.group, project.name, project.version
- override per-publication
- multiple artifacts from one project
- override != mutating project.version
basics
~10 sInside a MavenPublication you set groupId, artifactId, and version directly. If you omit them, Gradle defaults groupId to project.group, version to project.version, and artifactId to project.name.
solid answer
~30 sA `MavenPublication` carries three coordinate properties: `groupId`, `artifactId`, and `version`. When you don't set them, Gradle derives defaults — `groupId` from `project.group`, `version` from `project.version`, and `artifactId` from `project.name`. You can override any of them inside the publication block, which is common when one project produces several artifacts (e.g. a `-core` and a `-bom`) or when the published name should differ from the Gradle project name. Overriding here does **not** change `project.group`/`project.version`; it only affects this publication's published coordinates and the generated POM's `<groupId>/<artifactId>/<version>`. Setting `project.group`/`project.version` at the top level is the idiomatic way when all publications share one GAV.
code
kotlin · 10 linespublishing {
publications {
create<MavenPublication>("library") {
from(components["java"])
groupId = "com.acme"
artifactId = "payments-core"
version = "1.4.0"
}
}
}go deeper
Name the three coordinates and the three project defaults they fall back to.
Explain when to override per-publication (multiple artifacts, BOMs, renamed modules) and that artifactId defaults to project.name.
Discuss keeping GAV centralized on the project vs. per-publication, and lazy evaluation gotchas when reading project.version early.
Frame GAV as the public API contract of a module and how org conventions (reverse-DNS groups, naming) are governed across many publishing builds.
## What "GAV" means Every artifact in a Maven-style repository is addressed by three coordinates, collectively called **GAV**: - **G**roup id — a namespace, usually reverse-DNS (`com.acme`). - **A**rtifact id — the module name (`payments-core`). - **V**ersion — the release identity (`1.4.0`, `2.0.0-SNAPSHOT`). A consumer declares `com.acme:payments-core:1.4.0`, so these three strings are the public contract of what you publish. ## Where coordinates come from in Gradle The `maven-publish` plugin contributes a `publishing { publications { ... } }` block. Inside a `MavenPublication` you can assign coordinates explicitly: - `groupId`, `artifactId`, `version` are mutable `String` properties on the publication. - If you leave them unset, Gradle fills in **defaults at publish time**: `groupId = project.group.toString()`, `version = project.version.toString()`, `artifactId = project.name`. So for the common case you set nothing on the publication and instead set `group` and `version` once on the project — every publication inherits them. ## When you override on the publication You override directly on the `MavenPublication` when a single Gradle project emits **more than one** set of coordinates, or when the published name must diverge from the project's folder name. Classic cases: - A BOM published as `acme-bom` from a project whose `project.name` is `bom`. - A renamed artifact for backward compatibility. - Multiple publications in one project, each with its own artifactId. Overriding the publication's `version` does **not** mutate `project.version`; the two are independent once you set the publication value explicitly. ## Example ```kotlin publishing { publications { create<MavenPublication>("library") { from(components["java"]) // override only what differs from project defaults: groupId = "com.acme" artifactId = "payments-core" version = "1.4.0" } } } ``` ## Pitfalls - Coordinates are resolved lazily; if you read `project.version` too early in configuration you may capture a stale value. - `artifactId` defaults to `project.name`, which is the **directory name** unless overridden in `settings.gradle(.kts)` — a frequent surprise.
- If you set project.group and project.version but nothing on the publication, what coordinates get published?groupId = project.group, version = project.version, artifactId = project.name (the directory name unless overridden in settings).
- Why might artifactId differ from what you expect even with no override?Because it defaults to project.name, which is the project directory name, not necessarily the human-friendly module name; it must be set in settings.gradle if you want a different one.
saying these in an interview costs you the question
- Claiming you must always set coordinates explicitly on every publication — defaults from project.group/name/version usually suffice.
- Thinking overriding the publication's version also changes project.version.