Publishing artifacts on Maven Central is a close equivalent to publishing Python packages on PyPI (aka the cheese shop). If you have published packages on PyPI before, you will find these steps a bit more advanced than those you tackled in Python.
0. First things first
1. Sign up
2. Apply for your namespace
3. Get the GPG key
4. Save your secrets
5. Set up your project to upload
6. Upload
7. Publish on Maven Central
8. Use it
0. First things first
No one can publish to Maven Central directly. You have to publish your artifacts to an approved repository
, then release
them to Maven Central.
Sonatype OSS Nexus
is an approved repository hosting service run by Sonatype (the company that runs Maven Central) which provides hosting free of charge specifically for open-source projects.
1. Sign up
namespaces
, packages
and groupIds
, right? To upload an artifact into a Sonatype repo, your artifact should be created using a specific namespace
in order to prevent naming collisions. The package
and groupId
are also required. You must apply for a namespace
from Sonatype. To apply for a namespace
, you will need to raise an issue (see below) on the Sonatype Jira
instance. In order to do that, you will first need to sign up for a Sonatype Jira account.
Tips
- Sign up with your company email if you are going to apply for a
groupId
which will be the domain name of your company. - Remember your user name and password. It is not only used for raising issues. It is used for uploading your artifacts as well.
2. Apply for your namespace
Sonatype
employee. It should be fast, within 2 hours.
Tips
After your application is approved, you will gain permission to the following URLs:
- Repository: https://oss.sonatype.org/service/local/staging/deploy/maven2/
- Snapshot repository: https://oss.sonatype.org/content/repositories/snapshots/
3. GnuPG keys (or GPG keys for short)
Packages to maven central must be ‘signed’ prior to uploading. The signature uses a set of encryption keys which should only be know to authors publishing for a given identity.
If your organisation already has signing keys, then it makes sense to use the keys already available. For the first use, it may be necessary to create keys under the instructions below.
In order to publish, the follow are required:
Key ID
of your newly generated key pair.- The key
password
for this key pair. - The secret key ring file called
secret-keys.gpg
Cross Platform Key Creating Instructions.
If you use a Mac, you could use the GPG Suite as described below as alternative, however, there are cross platform tools for GPG keys as described on this github page, using the tools which are available as binaries (as well as source for those desiring to build their own) for download for :
- Windows (32bit full featured or simple version),
- MacOs/OS X (GpgTools or GnuPG)
- Linux: Debian or RPM
- Android
- VMS/ Open VMS
- RISC OS
.
MacOS: GpgTools
If you use Mac, you could download and install GPG Suite. When opening the app, the generate new key pair
dialogue box should automatically open, otherwise press New
on the tope menu in the app to create your key pair.
Name
is the user name that you used when you registered onSonatype
.Email
is the email address that you used when you registered onSonatype
.- Enter a unique
password
twice to confirm it. Remember thispassword
too, you are going need it. Advanced options
can be left as they are.
Needs confirmation: I don’t know whether the user name and email need to match, but I matched them both just in case.
After successfully creating your key, either accept the option to Upload Public Key
in the dialogue box displayed or right-click your key in the key list in the app and select Send Public Key to Key Server
to publish your public key.
To find your Key ID
double-click your key in the key list in the app, select the Key
tab if not already selected, note it down.
In Terminal on your Mac, use this command to get the secret key ring file:gpg --export-secret-keys YOUR-KEY-ID > secret-keys.gpg
Enter the passphrase you used when you created the key in the Pinentry Mac
dialogue box when it is displayed. The secret-keys.gpg
file will be located in the folder where you ran GPG export command above. Take note of the path to this file, it will be needed later.
Windows instructions:
- Download and install gpg4win from https://www.gpg4win.org/download.html
- Open Kleopatra once gpg is installed.
- Open the file tab > generate a new key pair.
- Create a personal OpenPGP key pair using the following details.
- Name is the user name that you used when you registered on Sonatype.
- Email is the email address that you used when you registered on Sonatype.
- The advanced settings can be left as the default values.
- Click create a key pair.
- Enter and repeat a passphrase. Remember this value; you will need it later.
- Make a note of the final eight characters of the Key-ID for your new key pair.
- When you add to gradle.properties you only need the final eight characters of your Key-ID, not the full character sequence.
- In your command line, use this command to get the secret keyring file:
gpg --export-secret-keys YOUR-KEY-ID > secret-keys.gpg
. Use the full Key-ID for this.
4. Save your secrets
gradle.properties
file or open it if you already have one and add the following code:
nexusUsername=YOUR_SONATYPE_USER_NAME
nexusPassword=YOUR_SONATYPE_USER_PASSWORD
signing.keyId=KEY_ID
signing.password=KEY_PASSWORD
signing.secretKeyRingFile=/PATH/TO/SECRET/RING/FILE
Tips
- Add the
gradle.properties
to your project root folder rather than in the.gradle
orgradle
folders. Why? I am using Intellij IDEA and my IDEA gradle settings file could not be found if I put it either of those two folders. I had to put it in the project root. - ADD THE
gradle.properties
FILE TO YOUR PROJECT’S.gitignore
. You never want to release this to the repo (it has your key password).
5. Set up your project to upload
Maven
gradle plugin, but I choose to use com.bmuschko.nexus
because I found it easier to understand and use.
Below is the full code listing of the build.gradle
com.bmuschko.nexus
plugin. Add it to your current gradle code:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.bmuschko:gradle-nexus-plugin:2.3.1'
}
}
apply plugin: 'com.bmuschko.nexus'
archivesBaseName = 'teachUpload-jvm'
group = "com.yourCompany.package"
version = "0.1"
modifyPom {
project {
name 'teachUpload'
description 'Teaching how to use gradle.'
url 'https://bitbucket.org/objdict/objjson'
inceptionYear '2018'
scm {
url 'https://bitbucket.org/objdict/objjson'
connection 'scm:https://bitbucket.org/objdict/objjson.git'
developerConnection 'scm:git://bitbucket.org/objdict/objjson.git'
}
licenses {
license {
name 'The Apache Software License, Version 2.0'
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
distribution 'repo'
}
}
developers {
developer {
id 'albertgao'
name 'Albert Gao'
email 'albert.gao@salect.co.nz'
}
}
}
}
extraArchive {
sources = true
tests = true
javadoc = true
}
nexus {
sign = true
repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2/'
snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots/'
}
Tips
- You don’t need to create the
sourceJar
in thebuild.gradle
settings file above. Thecom.bmuschko.nexus
plugin will add it for you.
6. Upload
uploadArchives
task to your gradle (it might reside in the upload
category (if you can’t find it in your IntelliJ IDEA gradle side-panel)).
Double click it to execute the uploadArchives
task.
You might see the following error when you first upload:Could not find metadata com.yourCompany.package:teachUpload-jvm/maven-metadata.xml in remote (https://oss.sonatype.org/service/local/staging/deploy/maven2/)
- This is not an error, just information – this is your first time, so no meta file previously existed on the server.
- Your package will have already been uploaded if this is the only information displayed.
Congratulations! After completing all of these steps, your package should finally have been uploaded onto Sonatype OSS Nexus
.
7. Publish on Maven Central
There are two ways to get your artifacts onto Maven Central:
- Auto-publish via gradle
- Manually publish via Nexus website
7.1 Auto-publish via gradle
Just add the following gradle code:
plugins {
id 'io.codearte.nexus-staging' version '0.11.0'
}
nexusStaging {
// optional if packageGroup == project.getGroup()
packageGroup = "org.mycompany"
// when not defined will be got from server using "packageGroup"
stagingProfileId = "yourStagingProfileId"
}
Now several gradle tasks will exist:
- closeRepository – closes an open repository with the uploaded artifacts. There should be just one open repository available in the staging profile (possible old/broken repositories can be dropped with Nexus GUI)
- releaseRepository – releases a closed repository (required to put artifacts to Maven Central aka The Central Repository)
- closeAndReleaseRepository – closes and releases a repository (an equivalent to closeRepository and then releaseRepository)
- getStagingProfile – gets and displays a staging profile id for a given package group. This is a diagnostic task to get the value and put it into the configuration closure as stagingProfileId.
Now you should already have uploaded your artifacts to the Nexus repo. All you need to do now is to run the closeAndReleaseRepository, and your artifacts will be added to Maven Central (within 10 min ~ 2 hours).
Tips:
- If you have a multiple project gradle setup. You just need to add this plugin at the root level.
7.2 Manually publish via Nexus website
The reason we still need this publishing option is that sometimes there are some errors during the auto-publishing phase. After publishing, check the status on the website. Follow the steps below to publish manually if the auto option is unsuccessful.
- Open the Nexus Repository Manager.
- Click the
Log In
button in the upper right corner of the screen. - On the right-hand side, click
Staging Repositories
. - Search your project by following this search pattern: if for example, your
groupId
iscom.google
, then entercomgoogle
. - Select the correct item and click the
Close
button to close it – this action finalizes the upload. - Click the
Refresh
button to get the latest updates (remember this trick, no ajax yet). - If see any errors:
- You can inspect them at the
Activity
panel. - You will need to:
-
Drop
this upload - Find and fix the errors in your local folder
- Run the
uploadArchives
task again - Then finalize the upload by pressing the
Close
button again and then continue
-
- You can inspect them at the
- If you see NO errors:
- Click the
Release
button to publish
- Click the
Congratulations! Your artifact should have finally been uploaded to Maven Central.
8. Use it
build.gradle
file in your project, add the following if you want to use this package:
repositories {
mavenCentral()
}
dependencies {
compile "com.yourCompany.package:teachUpload-jvm:0.1"
}
The pattern in our example is: groupId:archiveBaseName:versionNumber
where:
groupId = com.yourCompany.package archiveBaseName = teachUpload-jvm versionNumber = 0.1