skip to content

How do you apply the maven-publish plugin and declare a basic Maven publication that publishes your project's Java library?

level: juniorimportance: must knowfreq 70%

answer

  1. plugins { `maven-publish` }
  2. publishing { publications { } }
  3. create<MavenPublication>("maven")
  4. from(components["java"])
  5. java SoftwareComponent → POM + module metadata

basics

~10 s

Apply the maven-publish plugin, then in a publishing { publications { } } block create a publication of type MavenPublication and call from(components["java"]) so it picks up your library's jar and dependencies.

solid answer

~40 s

Add `maven-publish` to the `plugins {}` block. That plugin contributes a `publishing` extension. Inside `publishing { publications { } }` you register a publication of type `MavenPublication` — in Kotlin DSL `create<MavenPublication>("maven") { ... }`, in Groovy `maven(MavenPublication) { ... }`. The key line is `from(components["java"])`, which wires the publication to the `java` SoftwareComponent contributed by the `java`/`java-library` plugin. That component carries the main jar artifact plus the resolved API/implementation dependencies, which Gradle turns into a generated POM and (for modern metadata) a Gradle Module Metadata file. Without `from(components[...])` the publication has no artifacts. The publication name (`"maven"`) is arbitrary and only affects the generated task names.

code

kotlin · 12 lines
kotlin
plugins {
    `java-library`
    `maven-publish`
}

publishing {
    publications {
        create<MavenPublication>("maven") {
            from(components["java"])
        }
    }
}

go deeper

for a junior

Recall the three lines: apply the plugin, create a MavenPublication, call from(components["java"]).

for a middle

Explain that the java component carries both the jar and dependency metadata, and that the publication name only affects task names.

for a senior

Distinguish create vs register (lazy), note Gradle Module Metadata is emitted alongside the POM, and that repositories are a separate concern.

for a principal

Frame software components as the variant-aware publishing contract and discuss standardizing this block across many modules via a convention plugin.

## What the maven-publish plugin does The `maven-publish` plugin is Gradle's modern (post-1.0 "new publishing") mechanism for producing Maven-style artifacts: a JAR, a generated `pom.xml`, and Gradle Module Metadata. It replaces the legacy `maven` plugin's `uploadArchives`. Applying it adds a `publishing` extension to the project. ## The three layers 1. **Apply the plugin** in the `plugins {}` block. 2. **Declare publications** — *what* to publish. A publication of type `MavenPublication` represents one set of coordinates + artifacts + metadata. 3. (Repositories — *where* — are a separate concern handled by the `repositories {}` block inside `publishing`.) ## from(components[...]) is the crux The `java` and `java-library` plugins register a `SoftwareComponent` named `java`. A software component is Gradle's abstraction for "the consumable outputs of this project": its main artifact(s) and the variant-aware dependency information. Calling `from(components["java"])` tells the publication to derive its artifacts and POM dependencies from that component. This is why: - The main jar is published automatically. - `api`/`implementation` dependencies appear in the POM with the correct scopes (`compile`/`runtime`). - Gradle Module Metadata is generated alongside the POM. Without `from(...)` (or an explicit `artifact(...)`), the publication publishes only an (empty) POM. ## Registering vs. creating In Kotlin DSL you typically write `create<MavenPublication>("maven")`; the `publications` container also supports `register<MavenPublication>("maven")` for lazy configuration. The string name only influences generated task names (e.g. `publishMavenPublicationToMavenLocal`). ```kotlin plugins { `java-library` `maven-publish` } publishing { publications { create<MavenPublication>("maven") { from(components["java"]) } } } ``` That is the minimal complete setup — coordinates default to the project's group/name/version.

  • What does from(components["java"]) actually contribute to the publication?
    It wires in the `java` SoftwareComponent: the main jar artifact plus variant-aware dependency information, which Gradle renders into the POM (with compile/runtime scopes) and Gradle Module Metadata.
  • What happens if you omit from(components[...]) entirely?
    The publication has no artifacts; Gradle publishes only a POM (effectively empty of dependencies), and your jar won't be uploaded unless you add explicit artifact(...) entries.

saying these in an interview costs you the question

  • Confusing the legacy `maven` plugin / `uploadArchives` with the modern `maven-publish` plugin.
  • Thinking you must manually add the jar with `artifact(jar)` — `from(components["java"])` already does it.

context