Publishing java libraries to Maven Central, the manual
Table of Contents
What is Sonatype and why is it needed?
Sonatypeis a company that provides a staging repository, which performs validation and allows to push the builds that pass all checks to the Central repo. Without it, basically, you can’t easily publish anything to the Central easily, unless you’re an Apache project or similar.
Follow their getting started guide to set up the needed credentials. This should be easy - you create a JIRA account and you create a ticket in JIRA to claim your namespace (groupId in Maven terms). If you have a github account, for example, http://github.com/chhh, you’ll want to claim com.github.chhh.
You’ll need to set up and publish your GPG key for signing artifacts. This is described here.
In short you’ll need to install gpg or gpg2. I did it on Windows and already had a working gpg that came with git installation. So I happily used that to generate my key with (create it with a passphrase!):
Make sure to check that the generated key does not have sub keys for
signing. First issue
gpg --list-keys, the output should be like:
$ gpg --list-keys /c/Users/<username>/.gnupg/pubring.gpg --------------------------------- pub 2048R/DA123C12 2012-01-24 uid Dmitry Avtonomov (chhh) <firstname.lastname@example.org> sub 2048R/3E123123 2012-01-24
Notice, that there is one pub key and one sub key. You want this sub key
to not be Usage: C type.
gpg --edit-key DA123C12
gpg (GnuPG) 1.4.20; Copyright (C) 2015 Free Software Foundation, Inc. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Secret key is available. pub 2048R/DA100C23 created: 2012-01-24 expires: never usage: SC trust: ultimate validity: ultimate sub 2048R/3E123123 created: 2012-01-24 expires: never usage: E [ultimate] (1). Dmitry Avtonomov (chhh) <email@example.com>
In this case the sub key is usage: E, it’s used for encryption only, so we’re good to go, otherwise you’d need to delete or revoke it. Published the key with:
gpg --keyserver hkp://pool.sks-keyservers.net --send-keys <key-id>
The previous steps created the keychain file in
However, when I later installed the native windows gpg from
https://www.gnupg.org/download/ I’ve found
that it used a different default path and I could not list the key anymore.
Addind a new environment variable
GNUPGHOME and set it to
C:\Users\<username>\.gnupg. Now the gpg that was installed in windows could
read the old keychain, which meant maven could now use that key to sign files.
Configuring Maven to know where to get the signing key
Check out your
<maven-install-apth>/conf directory. There should be a
settings.xml file. Copy that over to your
<user-home>/.m2, unless you
already have it there. Add the following to
<profiles> <profile> <id>ossrh</id> <activation> <activeByDefault>true</activeByDefault> </activation> <properties> <gpg.executable>gpg</gpg.executable> <gpg.passphrase>passphrase-you-used-when-created-gpg-key</gpg.passphrase> </properties> </profile> </profiles>
It’s ok to have your passphrase set here as this is your user-specific configuration file. If you don’t want to specify that, however, there will be an option for you to provide that passphrase every time you publish.
Configuring Maven to know the credentials for Sonatype servers
You’ll provide the log-in credentials in the same
settings.xml maven file in
~/.m2 directory. If you don’t want to provide the actual username and
password, log in to your account at
https://oss.sonatype.org. In the top right corner
Log-In, then click your username and select
Profile. On the new screen
there’s a dropdown with two choices: Summary and User Token. Select the user
token, it will give you the info. In the
settings.xml file add:
<servers> <server> <id>ossrh</id> <username>user-name-token</username> <password>password-for-token</password> </server> </servers>
Satisfying requirements to pass all checks upon submission to Sonatype
There’s a lot of meta-info required to satisfy all the requirements. As you will
be using the same
groupId for all your artifacts, it’s easier to put all the
extra information to a parent POM. You can find an example parent project here:
This project consists only of the POM file, specifying the credentials, basic
info and publishing locations. It adds some to the
release target as well.
It’s ok to just clone that repo and change the information to what you like.
You will set this POM as the
<parent> of the projects you wish to publish to
Central. As it will be the parent POM, anyone who will want to build your
artifacts will need to have that POM, so the first thing is to publish this
project to Central by itself.
Publishing parent POM project to Central
We’ll be using maven-release plugin. Make sure that:
- You have SCM information configured.
- In this parent POM you set the
versionto something like
The release plugin will use that information to create the build. It will remove
SNAPSHOT part, build the project, create a new tag in SCM, push everything
to remote, bump up the version in POM and re-add SNAPSHOT back to it. Now
If you encounter any problems with
release:perform you can always do
mvn release:rollback to undo any changes done by
Publishing the project to Central
In your actual project set the
<parent> <groupId>com.github.chhh</groupId> <artifactId>sonatype-ossrh-parent</artifactId> <version>0.1</version> <relativePath>../sonatype-ossrh</relativePath> </parent>
Notice how we used
relativePath to give maven a hint at where to search for
this POM. The parent project was resiging in a sibling directory next to the
project directory in this case. Otherwise the POM would have to be in the parent
directory of your project.