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
groupIdwhich 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 IDof your newly generated key pair.- The key
passwordfor 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.
Nameis the user name that you used when you registered onSonatype.Emailis the email address that you used when you registered onSonatype.- Enter a unique
passwordtwice to confirm it. Remember thispasswordtoo, you are going need it. Advanced optionscan 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.propertiesto your project root folder rather than in the.gradleorgradlefolders. 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.propertiesFILE 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
sourceJarin thebuild.gradlesettings file above. Thecom.bmuschko.nexusplugin 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 Inbutton 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
groupIdiscom.google, then entercomgoogle. - Select the correct item and click the
Closebutton to close it – this action finalizes the upload. - Click the
Refreshbutton to get the latest updates (remember this trick, no ajax yet). - If see any errors:
- You can inspect them at the
Activitypanel. - You will need to:
-
Dropthis upload - Find and fix the errors in your local folder
- Run the
uploadArchivestask again - Then finalize the upload by pressing the
Closebutton again and then continue
-
- You can inspect them at the
- If you see NO errors:
- Click the
Releasebutton 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