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.
Getting started
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.
GPG signing
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!):
gpg --gen-key
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) <email@gmail.com>
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@gmail.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>
Windows caveat
The previous steps created the keychain file in c:/Users/<username>/.gnupg
.
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>
:
<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
click 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:
https://github.com/chhh/sonatype-ossrh-parent.
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
version
to something like0.1-SNAPSHOT
.
The release plugin will use that information to create the build. It will remove
the 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
execute:
mvn release:prepare
mvn release:perform
If you encounter any problems with release:perform
you can always do
mvn release:rollback
to undo any changes done by release:prepare
.
Publishing the project to Central
In your actual project set the parent
:
<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.