Happy Employees == Happy ClientsCAREERS AT DEPT®
DEPT® Engineering Blogjava

Publishing to Maven Central, a retrospective

Package management can be something of a headache, but it doesn't have to be that way. Here's some tips to get you on your way with Maven Central.

As part of releasing spring-sql-explain-logger, a new logging library created at DEPT, I needed to upload the package to a repository so anyone could easily add it to their Java projects. Package management can be something of a headache, and my experience showed me that Maven Central is no exception.

Don't get me wrong - after all is said and done, it works well. For this project, we're dealing with Maven. So there should be no surprises, especially for a seasoned Java developer. The whole release is run through Maven plugins.

But beware! I found myself inadvertently stuck spinning my wheels a couple times. So I'm writing this post as a way to hopefully help people avoid some snags I faced on the journey of releasing a project to Maven Central for the first time.

First tip: always reference the official Sonatype docs for Maven (general Sonatype docs are found here). Anything related to the release is spelled out clearly, and correctly, there.

Let's talk about what might happen when you don't use the Sonatype docs. I copy-pasted a config from an old tutorial that had <nexusUrl>...</nexusUrl> set as https://oss.sonatype.org/ instead of https://s01.oss.sonatype.org/. So when I tried releasing with mvn release:perform I was faced with the unexplained response: HTTP/1.1 403 Forbidden. I had to correspond with Sonatype through their Jira, determine that the issue was on my end, and piece through the official docs comparing each section to my pom.xml until I found the offending <nexusUrl>. So please trust me when I say that you should treat the Sonatype docs as a single source of truth.

Another thing that confused me in the beginning deals with the two Nexus URLs: snapshot and release. Uploading artifacts to the snapshot URL creates a snapshot release. On the other hand, it's a somewhat subtle point, but the release URL is where releases are staged, rather than the final destination where the release is stored and publicly available. So uploading to the release URL creates a "staging repo" that can be approved, and only then does it sync to Maven Central where it's available to the public. Remember that once you do a release, there's no going back. So be very careful to review things ahead of time. Baeldung has a great article explaining snapshot and release repositories.

The whole journey of setting up the release process goes something like this:

This might not seem like a lot, but there are details I'm leaving out, enough that I decided to dedicate an entire document to our release process.

Keep in mind that things are a little more complicated if you're working in an organization. First, consider creating multiple accounts to access the Sonatype Jira so that multiple people can perform a release. Also, find a way to share the GPG key and passphrase. An organization-wide password manager that can store files should be adequate. And last, you'll need access to the DNS server in order to claim ownership over the domain. This involves adding a TXT record to your DNS server.

There's also a handy plugin we're using: maven-release-plugin.  It handles the rote steps of updating version values in pom.xml, creating release commits, and tagging the release. Afterward, it calls nexus-staging-maven-plugin to handle the release to Maven Central. We disabled autoReleaseAfterClose, so that the release needs to be manually approved from the Nexus web interface.

That wraps up all the ins and outs I learned from releasing a project onto Maven Central. If you stick to these tips you should be up and running in no time!