How to publish a library on Maven Central

Guozheng Ge
5 min readJul 4, 2022

Now you have a great library (Java, Scala, etc.) hosted on GitHub, how do you share it with the world? One of the common way is to release it on Maven Central, a public and free artifact hosting service used by millions of developers.

Sonatype is the company that provides Open Source Software Repository Hosting (OSSRH) that allows open source developers to publish their artifacts on Maven Central.

From a high level, you use your build tool to publish the library to Nexus staging repository, then use Nexus Repository Manager Web UI to release the binary to Nexus public repository, which syncs it to Maven Central and makes it available for other people to use.

Nexus provides a nicely written document about publishing and releasing, I am providing a quick summary based on my own experience here. Some problems and tricks that I encountered might not be covered in the official document.

Register a Jira Account on Sonatype.org Jira System and Open A Ticket

Follow the links to open an account and open a ticket:

  1. Create your Jira account
  2. Create a New Project ticket

The Jira account username and password will be used for publishing your artifact.

The project Jira ticket will be used to provision permission to your username and create repository in staging. Otherwise, you will get 403 errors.

According to the document, it takes up to 2 days for the ticket to be resolved. But based on my experience, it took several hours before auto-resolved by a bot.

One trick here is that you need to make sure the group id reflects a domain name that you have the ownership. See the next section on this topic. Otherwise, the ticket cannot be auto-approved and provisioned.

Here is a sample ticket for my project: https://issues.sonatype.org/browse/OSSRH-82272

Ownership Verification of the Group ID and Domain Name

One of the requirements to publish through OSSRH is that the group id needs to reflect a domain name you have the ownership (recall that group id or package name is the reverse of a domain name). Without this, your Jira ticket won’t be approved.

By using a free SCM system like GitHub, you get your domain name for free, e.g. io.github.guozheng is mine. For other SCM systems like GitLab, Gitee, Bitbucket, Sourceforge, see this document. Note that you also need to create a public dummy GitHub project with the Jira ticket number as the project name to prove that you do own the GitHub account.

If you actually own a domain name and want to use that as group id, you will need to create a TXT record in your DNS service.

Set up GPG to Sign the Artifacts

Another requirement to publish through OSSRH is that all the artifacts need to be signed with GPG. You can follow the instructions from this document to generate the key pair and upload a public key server such as keys.openpgp.org.

If you are using Mac OS, you can install GPG Suite and use GPG Keychain to generate and upload to the public key server.

Later in the configuration used to sign the artifact, you will need a secring.gpg file, which does not exist with default GPG installation. You can generate the file using this command:

gpg — keyring secring.gpg — export-secret-keys > ~/.gnupg/secring.gpg

Set up Build Tool to Publish through OSSRH

Assuming you are using Gradle, there are several different ways I found to publish your artifacts:

  • Use Maven Publish plugin: follow this document to set up build.gradle, then run “./gradlew publish”
  • Use a custom uploadArchives step: follow the steps in Sonatype document, then run “./gradlew uploadArchives”
  • Use Gradle Nexus Publish plugin: follow the instructions, then run: “./gradlew publishToSonatype closeSonatypeStagingRepository”

I ended up using Nexus Publish plugin and it worked well for me. It also provides extra functionality of closing the staging repository, which otherwise needs to be done manually.

Here is the sample build.gradle file for my project: https://github.com/guozheng/jvast/blob/master/build.gradle

Besides picking the publish plugin, you also need to make sure your build file satisfy all the other OSSRH requirements, this is very important, otherwise after you publish, the repository will not be able to close and release from staging to the public repository.

  • Use maven plugin to generate metadata and the pom.xml file
  • Use signing plugin to sign the artifacts, generating .asc files
  • After Feb 2021, instead of publishing to https://oss.sonatype.org/, publish to https://s01.oss.sonatype.org/ in your publish plugin config
  • Provide other metadata such as name, description, url, scm system (connection, developerConnection, url), license info, developer info
  • In the grandle.properties file in your home directory, profile properties for signing and OSSHR publishing credentials (this example is for using Nexus Publish plugin, other plugin might be slightly different, see plugin links above):

signing.keyId=<8 characters id>

signing.password=<password for the private key>

signing.secretKeyRingFile=<USER_HOME/.gnupg/secring.gpg>

sonatypeUsername=<Sonatype_jira_username>

sonatypePassword=<Sonatype_jira_password>

Use Nexus Repository Manager Web UI to Release to Public Repository

If you use Nexus Gradle Publish plugin, when “./gradlew publishToSonatype closeSonatypeStagingRepository” finishes successfully, then the artifacts are uploaded to Nexus staging repository with the state “closed”. You need to use the Web UI to manually release it.

First, you need to log onto: https://s01.oss.sonatype.org/, note that the login button is on the top right corner.

Log onto Nexus repository manager Web UI

Second, view your published artifacts by selecting “Build Promotion” -> “Staging Repositories”. You can see the staging repositories you published each time, with different status like “open” or “close”.

If you see red error icons, that means the published staging repository has errors. You need to select the error repository, then select the “Activity” tab to view the detailed errors. For example, I had missed the step to upload my public PGP key to the key server, so the signature validation failed.

If there is no error for the published staging repository, then you can select it and locate the “release” button, then press release button to release to the public repository. You can verify that your artifact is published by checking the public repository.

After your artifact has been released, it will be synced to the Maven central in a few hours.

Congratulations, Your library is now available to share with the world!

References

--

--