skip to content

You produce two artifacts (a core library and a BOM) from one Gradle project. How do you give each its own artifactId while sharing one group and version?

level: middleimportance: should knowfreq 35%

answer

  1. publication-level coordinates
  2. multiple MavenPublications, one project
  3. inherit group/version, override artifactId
  4. library + BOM move together
  5. no two publications share same GAV

basics

~10 s

Create two MavenPublications in the same project. Let both inherit groupId and version from project.group/version, but set a distinct artifactId on each so they publish as separate coordinates.

solid answer

~40 s

Coordinates are per-publication, so one project can emit several. Declare multiple `MavenPublication`s under `publishing { publications { } }`. Each can leave `groupId`/`version` unset to inherit `project.group`/`project.version`, while overriding `artifactId` to differentiate — e.g. `acme-core` from `components["java"]` and `acme-bom` from `components["javaPlatform"]`. Because all share the project's group and version, they version together, which is usually what you want for a library and its BOM. Each publication produces its own POM (and Module Metadata) and its own generated `publish<Name>PublicationTo<Repo>Repository` tasks. The only hard rule: two publications must not resolve to the **same** GAV, or you'd have a coordinate collision; differing artifactIds satisfy that.

code

kotlin · 12 lines
kotlin
publishing {
    publications {
        create<MavenPublication>("core") {
            from(components["java"])
            artifactId = "acme-core"
        }
        create<MavenPublication>("bom") {
            from(components["javaPlatform"])
            artifactId = "acme-bom"
        }
    }
}

go deeper

for a junior

Know that coordinates live on the publication and you'd set a different artifactId.

for a middle

Show two publications inheriting group/version and overriding artifactId, and explain the collision rule.

for a senior

Discuss lockstep versioning, BOM-pins-library relationships, and the generated per-publication tasks.

for a principal

Set conventions for when to split into multiple publications vs. multiple projects across the org's library portfolio.

## Coordinates are a property of the publication, not the project A single Gradle project can declare any number of `MavenPublication`s, and **each** carries its own `groupId`/`artifactId`/`version`. That is what lets one build emit, say, a library jar and a BOM (platform) as two distinct modules. ## The pattern ```kotlin plugins { `java-library` `java-platform` `maven-publish` } group = "com.acme" version = "1.4.0" publishing { publications { create<MavenPublication>("core") { from(components["java"]) artifactId = "acme-core" // group/version inherited } create<MavenPublication>("bom") { from(components["javaPlatform"]) artifactId = "acme-bom" } } } ``` Here both publications inherit `groupId = com.acme` and `version = 1.4.0` from the project, and differ only by `artifactId`. Consumers see `com.acme:acme-core:1.4.0` and `com.acme:acme-bom:1.4.0`. ## Why share group and version A library and its BOM should move together: releasing `acme-core:1.4.0` alongside `acme-bom:1.4.0` keeps the version story coherent and lets the BOM pin the exact library version. Sharing `project.version` makes that automatic — bumping one line bumps both. ## Generated tasks Each publication gets its own publish tasks: `publishCorePublicationToMavenRepository`, `publishBomPublicationToMavenRepository`, etc., plus the aggregate `publish`. (Task generation itself is the sibling topic; here the point is each distinct publication produces its own.) ## The one rule you cannot break Two publications in the same build must not have **identical** GAV coordinates. If two publications collide on group+artifact+version, the build is ambiguous/invalid. Differentiating `artifactId` (or, less commonly, group or a classifier strategy) avoids this. ## Common mistakes - Forgetting to override `artifactId` on the second publication, so both default to `project.name` and collide. - Setting `version` on only one publication and forgetting the other, causing version drift between the library and its BOM.

  • What happens if both publications keep the default artifactId?
    Both default to project.name, producing identical GAV coordinates — a collision that makes the publishing setup invalid/ambiguous.
  • Why is it desirable for the library and BOM to share project.version?
    They release in lockstep, so the BOM always pins the matching library version and a single version bump updates both.

saying these in an interview costs you the question

  • Suggesting you need separate Gradle projects just to get a second artifactId.
  • Allowing two publications to resolve to the same group:artifact:version.

context