skip to content

Publishing and Artifacts

Publishing from Gradle: publication models, what a software component actually contains, target repositories and credentials, signing, and artifact transforms. Interviewers ask because publishing is where Gradle's variant model becomes visible to the outside world.

on this pageshow

explore

questions

95 · 4 sections

How do you set the groupId, artifactId, and version on a MavenPublication, and how does that relate to project.group and project.version?

level: juniorimportance: must knowfreq 70%
basics
~10 s

Inside 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.

open as a page

What does the publishToMavenLocal task do, and where does it put your artifacts?

level: juniorimportance: must knowfreq 70%
basics
~10 s

publishToMavenLocal installs every publication into your local Maven repository on disk (by default ~/.m2/repository), so other local builds can resolve it via mavenLocal().

open as a page

How do you apply the ivy-publish plugin and declare a basic Ivy publication in a Gradle build?

level: juniorimportance: must knowfreq 35%
basics
~10 s

Apply the ivy-publish plugin, then inside publishing { publications { } } create a publication of type IvyPublication and add a component such as from components.java.

open as a page

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%
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.

open as a page

What is the pom { } block on a MavenPublication, and why might you need to populate it before publishing a library?

level: juniorimportance: must knowfreq 60%
basics
~10 s

The pom { } block lets you set metadata (name, description, url, licenses, developers, scm) written into the generated pom.xml. You populate it because repositories like Maven Central reject artifacts missing this metadata.

open as a page

How do the archiveBaseName, archiveVersion, and archiveClassifier properties on an archive task (like Jar) combine to form the final published artifact file name?

level: juniorimportance: must knowfreq 60%
basics
~10 s

Gradle assembles the name as [baseName]-[appendix]-[version]-[classifier].[extension]. So baseName 'app', version '1.0', classifier 'sources' produces app-1.0-sources.jar. Empty parts are skipped along with their dash.

open as a page

Where in the build script do you attach a custom artifact, and what's the minimal correct snippet to add a fat JAR to a Maven publication?

level: juniorimportance: must knowfreq 48%
basics
~10 s

Inside publishing { publications { ... } }, on the publication, call artifact(tasks.named("fatJar")). That single line adds the fat JAR as an extra file on that publication's coordinates.

open as a page

How do you make a Gradle Java library publish a sources jar and a javadoc jar alongside the main artifact?

level: juniorimportance: must knowfreq 70%
basics
~10 s

Inside the java { } block call withSourcesJar() and withJavadocJar(). Gradle registers sourcesJar and javadocJar tasks and attaches them to the java component, so they publish automatically.

open as a page

What is the Gradle Module Metadata (the `.module` file), and what does it describe that a traditional Maven POM cannot?

level: juniorimportance: must knowfreq 55%
basics
~20 s

It's a JSON file (module.module) Gradle publishes alongside the POM. It describes a module's variants, their dependencies, and attributes — richer info than a flat POM can express, so Gradle can pick the right variant when resolving.

open as a page

What is a SoftwareComponent in Gradle, and how does it relate to what gets published?

level: juniorimportance: must knowfreq 55%
basics
~10 s

A SoftwareComponent describes what a project produces for publication (its artifacts and dependencies). The MavenPublication's from(components.java) reads a component to populate the artifacts and POM/metadata that get published.

open as a page

What artifacts must a Maven Central release bundle contain beyond the main JAR, and why does Central reject a publication that is missing them?

level: juniorimportance: must knowfreq 62%
basics
~10 s

Each release must include the main JAR plus a sources JAR, a javadoc JAR, a POM, and PGP/GPG signatures (.asc) for every file. Central validation rejects bundles missing any of these.

open as a page

How do you supply a username and password to a Maven repository in a Gradle publishing block, and where does Gradle get those values from?

level: juniorimportance: must knowfreq 70%
basics
~10 s

Inside the repository, call credentials(PasswordCredentials::class). Gradle then reads <repoName>Username and <repoName>Password from gradle.properties or environment variables, where <repoName> is the repository's name.

open as a page

What does the publishToMavenLocal task do, and where does it put your artifacts?

level: juniorimportance: must knowfreq 60%
basics
~10 s

publishToMavenLocal installs your built artifacts (jar, POM, metadata) into the local Maven cache at ~/.m2/repository, so other local builds on the same machine can resolve them via mavenLocal().

open as a page

How do you declare a target Maven repository to publish your artifacts to in the maven-publish plugin, and what is the minimum you must specify?

level: juniorimportance: must knowfreq 70%
basics
~10 s

Inside the publishing { repositories { } } block add a maven { } repository and set its url. Optionally give it a name. That tells Gradle where to upload the published artifacts.

open as a page

What problem does the io.github.gradle-nexus.publish-plugin solve, and what would you have to do manually without it?

level: juniorimportance: must knowfreq 55%
basics
~10 s

It automates Sonatype staging: it creates a staging repository, publishes your artifacts into it, then closes and releases it from the build — so you don't click through the Nexus/Central Portal UI by hand.

open as a page

What does the `isRequired` property in Gradle's signing block control, and why would you set it conditionally instead of leaving it at its default?

level: juniorimportance: must knowfreq 55%
basics
~20 s

isRequired decides whether a missing or failing signature aborts the build. By default it's true. You set it conditionally (e.g. only for releases) so local or SNAPSHOT builds don't fail when no signing key is configured.

open as a page

At a basic level, what does the Gradle signing plugin produce, and why does publishing to Maven Central require it?

level: juniorimportance: must knowfreq 40%
basics
~10 s

It produces a detached PGP signature (.asc file) for each artifact (jar, POM, sources, javadoc). Maven Central requires these signatures so consumers can verify the artifacts are authentic and untampered.

open as a page

What does the Gradle `signing` plugin do, and why do you need it when publishing to Maven Central?

level: juniorimportance: must knowfreq 60%
basics
~10 s

The signing plugin uses PGP/GPG to create detached .asc signature files for your build artifacts. Maven Central requires every published file to be signed so consumers can verify authenticity.

open as a page

Walk through how `gradle.taskGraph.hasTask('publish')` works in a conditional signing predicate and why the task graph readiness matters.

level: middleimportance: must knowfreq 45%
basics
~20 s

gradle.taskGraph is the resolved DAG of tasks Gradle will run. hasTask('publish') returns true only when a publish task is scheduled. The graph is built after configuration, so the predicate must be read lazily at execution time, not during configuration.

open as a page

The Gradle signing plugin can obtain a PGP signing key in two main ways: useGpgCmd() and useInMemoryPgpKeys(...). What is the difference between these two approaches and when would you reach for each?

level: middleimportance: must knowfreq 55%
basics
~10 s

useGpgCmd() shells out to the local gpg binary and its keyring/agent. useInMemoryPgpKeys() takes the raw ASCII-armored key text and passphrase directly, so no gpg install or keyring is needed — ideal for CI.

open as a page