Skip to content

javachanges Publish To Maven Central Guide

1. Overview

This repository now includes the core Maven configuration required for Maven Central publishing:

CapabilityMeaning
sources.jarAttached through maven-source-plugin
javadoc.jarAttached through maven-javadoc-plugin
GPG signaturesAdded by maven-gpg-plugin during verify
Central uploadHandled by central-publishing-maven-plugin during deploy
Executable CLI jarMain-Class written by maven-jar-plugin

The publishing flow is isolated behind the Maven profile:

bash
-Pcentral-publish

That keeps everyday local builds separate from real Central publishing.

1.1 Publishing flow

Loading diagram...

2. Prerequisites

Before a real Maven Central release, make sure all of these are ready:

ItemRequired state
NamespaceVerified in Sonatype Central Portal
Portal tokenGenerated and stored locally or in CI secrets
GPG keyCreated and available on the publishing machine
VersionMust not end with -SNAPSHOT
Git tagRecommended for the release version

Note: never commit Portal tokens, GPG private keys, or passphrases into the repository.

3. Configure settings.xml

3.1 Default server id

The default Central server id in this repository is:

xml
<id>central</id>

That maps to the pom.xml property:

xml
<central.publishing.serverId>central</central.publishing.serverId>

Store your Sonatype Central Portal token in ~/.m2/settings.xml:

xml
<settings>
  <servers>
    <server>
      <id>central</id>
      <username>your portal token username</username>
      <password>your portal token password</password>
    </server>
  </servers>
</settings>

If you prefer another server id, override it during publish:

bash
mvn -Pcentral-publish -Dcentral.publishing.serverId=your-server-id deploy

The <id> inside settings.xml must match.

4. Configure GPG

4.1 Generate a key

bash
gpg --full-generate-key

4.2 Inspect keys

bash
gpg --list-secret-keys --keyid-format LONG

4.3 Warm up gpg-agent

bash
echo "test" | gpg --clearsign

Tip: prompts or keychain dialogs during signing are expected. Maven Central requires .asc signatures for published files.

5. Switch to a release version

If the repository currently has:

xml
<revision>1.0.0-SNAPSHOT</revision>

change it to a real release version first:

xml
<revision>1.0.0</revision>

After the release, move it forward again, for example:

xml
<revision>1.0.1-SNAPSHOT</revision>

6. Enrich the Sonatype Central artifact page

The Sonatype Central artifact page is not a customizable project website.

It mostly renders a fixed layout from standard POM metadata. That means:

  1. what the page can show depends on which standard fields are present in pom.xml
  2. already-published versions do not refresh just because you changed main
  3. richer metadata only shows up after the next real release that contains it

This repository now includes the main metadata fields that help Central show a fuller artifact page:

POM fieldPurpose
<name>artifact display name
<description>short artifact summary
<url>project homepage
<licenses>license details
<developers>developer details
<organization>organization details
<issueManagement>issue tracker link
<ciManagement>CI link
<scm>source control details
<inceptionYear>project start year

A representative metadata block looks like this:

xml
<organization>
  <name>sonofmagic</name>
  <url>https://github.com/sonofmagic</url>
</organization>

<issueManagement>
  <system>GitHub Issues</system>
  <url>https://github.com/sonofmagic/javachanges/issues</url>
</issueManagement>

<ciManagement>
  <system>GitHub Actions</system>
  <url>https://github.com/sonofmagic/javachanges/actions</url>
</ciManagement>

Note: Central uses a fixed template. You cannot add a custom logo section, README rendering, screenshots, arbitrary badges, or custom landing-page blocks there.

If your goal is a fuller Central page, check these fields before release:

CheckRecommendation
descriptionexplain the package in one sentence
urlpoint to the repo or project home
developersinclude at least name and url
organizationadd it when available
issueManagementlink to Issues
ciManagementlink to Actions or your CI
scmkeep connection, developerConnection, and url complete

7. Local preflight

Before deploy, validate the publishing build:

bash
mvn -Pcentral-publish -Dgpg.skip=true verify

This checks:

CheckMeaning
Main jarPackaging works
sources.jarSources are attached
javadoc.jarJavadocs are attached
Publish profilePublishing configuration is wired correctly

-Dgpg.skip=true is only for validating the build chain before real signing.

8. First manual release

For the first release, it is safer to upload and validate first instead of immediately auto-publishing.

The current defaults in pom.xml are:

ParameterDefault
central.autoPublishfalse
central.waitUntilvalidated

So the normal behavior is:

  1. upload the bundle to Central Portal
  2. wait for validation
  3. publish manually in the portal once validation passes

8.2 Publish command

bash
mvn -Pcentral-publish clean deploy

If your GPG key requires a passphrase, Maven will ask for it.

9. Auto-publish

Once the first manual release has proven stable, you can auto-publish:

bash
mvn -Pcentral-publish \
  -Dcentral.autoPublish=true \
  -Dcentral.waitUntil=published \
  clean deploy

That uploads, validates, publishes, and waits until the deployment reaches published.

9.1 Snapshot publishing with the Central plugin

Sonatype Central also supports publishing -SNAPSHOT versions through central-publishing-maven-plugin.

In this repository, that path is isolated behind:

bash
-Pcentral-snapshot-publish

The profile keeps the same source, javadoc, flatten, and GPG packaging chain, but uses the Central plugin with the Central Portal token server id instead of a separate maven-snapshots Maven server id.

Recommended local snapshot command:

bash
pnpm snapshot:publish:local

That script:

  1. resolves the current project snapshot version
  2. appends a unique UTC timestamp plus git rev-parse --short HEAD
  3. publishes the resulting revision through central-publishing-maven-plugin

If you want to override the generated build stamp, set JAVACHANGES_SNAPSHOT_BUILD_STAMP before running the command.

After a successful snapshot publish, verify it through:

TypeLocation
Snapshot repository roothttps://central.sonatype.com/repository/maven-snapshots/
Snapshot metadatahttps://central.sonatype.com/repository/maven-snapshots/io/github/sonofmagic/javachanges/<resolved-snapshot-version>/maven-metadata.xml
Snapshot artifacthttps://central.sonatype.com/repository/maven-snapshots/io/github/sonofmagic/javachanges/<resolved-snapshot-version>/javachanges-<timestamped-version>.jar

Note:

  • Sonatype's hosted snapshot repository is not directly browseable at the repository root
  • the current browse endpoint for hosted snapshots is temporarily unavailable
  • in practice, verify snapshots by opening maven-metadata.xml, opening the exact artifact URL, or resolving the dependency from a clean Maven/Gradle consumer
  1. make sure the worktree is clean: git status
  2. change revision to the real release version, for example 1.0.0
  3. run mvn -Pcentral-publish -Dgpg.skip=true verify
  4. confirm GPG works, then run mvn -Pcentral-publish clean deploy
  5. inspect the deployment in Sonatype Central Portal
  6. if you are still using manual publish mode, click publish in the portal
  7. create a git tag such as v1.0.0
  8. move the version to the next snapshot, such as 1.0.1-SNAPSHOT

11. Verify the result

After publishing, check:

TypeLocation
Central Portalhttps://central.sonatype.com
Maven Central artifact pagehttps://central.sonatype.com/artifact/io.github.sonofmagic/javachanges
Snapshot repository roothttps://central.sonatype.com/repository/maven-snapshots/

You can also verify dependency resolution in a small sample project:

xml
<dependency>
  <groupId>io.github.sonofmagic</groupId>
  <artifactId>javachanges</artifactId>
  <version>1.12.2</version>
</dependency>

And since this project also ships a Maven plugin, the shortest smoke test is usually:

bash
mvn javachanges:status

If you specifically want to verify the executable CLI artifact, you can still test:

bash
java -jar javachanges-1.12.2.jar

12. FAQ

12.1 Missing sources.jar or javadoc.jar

Cause: the central-publish profile was not enabled, or the packaging chain is broken.

Fix:

bash
mvn -Pcentral-publish -Dgpg.skip=true verify

12.2 Missing signatures

Cause: GPG is not configured correctly, or gpg-agent has not cached the passphrase.

Fix:

  1. run gpg --list-secret-keys --keyid-format LONG
  2. run echo "test" | gpg --clearsign
  3. rerun the Maven publish command

12.3 Authentication failures

Cause: the token in settings.xml is wrong, or the server id does not match.

Fix:

  1. inspect the <id> in ~/.m2/settings.xml
  2. inspect central.publishing.serverId in pom.xml
  3. confirm the token has not expired or been revoked

12.4 Why the Central page did not change immediately after I edited pom.xml

Cause: Central shows the metadata snapshot embedded in a published version, not the current state of your repository.

Fix:

  1. update the metadata in pom.xml
  2. publish a new version
  3. inspect the new version page in Central

13. Summary

The publishing commands for this repository reduce to:

GoalCommand
Pre-publish verificationmvn -Pcentral-publish -Dgpg.skip=true verify
Real publishmvn -Pcentral-publish clean deploy

13. References

ResourceLink
Sonatype Central Portal Maven publishinghttps://central.sonatype.org/publish/publish-portal-maven/
Sonatype publishing requirementshttps://central.sonatype.org/publish/requirements/
Sonatype GPG requirementshttps://central.sonatype.org/publish/requirements/gpg/
Maven Source Pluginhttps://maven.apache.org/plugins/maven-source-plugin/
Maven Javadoc Pluginhttps://maven.apache.org/plugins/maven-javadoc-plugin/
Maven GPG Pluginhttps://maven.apache.org/plugins/maven-gpg-plugin/

Released under the Apache-2.0 License.