Publishing a Java project into MVN Repository

Java, maven, programming

It turns out that this is quite an involved process with a lot of configuration and coordination w/ Sonatype. It took several days, upwards to a week or so, for me to get this working. Plan accordingly.

These notes are based on various articles out there, but updated to reflect learnings I had when going through the process.

Qualifications:

Here are some specifics for my project.

  • Project is hosted in GitHub as a public repo.
  • Project is a Maven project with a POM file at the root. It’s a multi-module project, but that shouldn’t change anything other than the fact that I publish the modules individually. There may be a way to publish all the modules simultaneously, but I haven’t explored that option.

Prerequisite:

  • Create an account with Sonatype. Start at https://issues.sonatype.org/secure/Dashboard.jspa and click “Sign up.”
  • Create an issue for the new project:
    • Project: “Community Support – Open Source Project Repository Hosting”
    • Type: “New Project”
    • Group Id: a domain I own (or something based on the project hosting like io.github.<user narme> or com.github.<user name>.
    • Project URL: GitHub URL to the project.
    • SCM URL: path to the repo (https://github.com/…/<project>.git)
    • Username(s): the Sonatype user name.

Configure project with Maven src and Javadoc plugins:

See https://github.com/bluedenim/log4j-s3-search/blob/master/appender-core/pom.xml#L106-L134

Create and publish an RSA key

  • Create a RSA key (e.g. using GnuPG’s “gpg –full-gen-key with 2048 bits)
  • Publish the key (e.g. “gpg –keyserver pool.sks-keyservers.net –send-key <my RSA key ID>“)

Configure Maven to talk to Sonatype servers:

Create/edit the file settings.xml under M2_HOME/config or M2_REPO/config:

Find the servers section and add:

<server>
  <id>ossrh</id>
  <username>my_sonatype_username</username>
  <password>my_sonatype_password</password>
</server>

Find the profiles section and add:

<profile>
  <id>ossrh</id>
  <activation>
    <activeByDefault>true</activeByDefault>
  </activation>
  <properties>
    <gpg.keyname>my RSA key ID</gpg.keyname>
    <gpg.passphrase>my RSA key's passphrase</gpg.passphrase>
  </properties>
</profile>

Use the same GPG key generated above.

Configure project for Maven DEPLOY Plugin:

Add the Maven Deploy Plugin. See https://github.com/bluedenim/log4j-s3-search/blob/master/appender-core/pom.xml#L64-L76

Add a distributionManagement section to the project POM. See https://github.com/bluedenim/log4j-s3-search/blob/master/appender-core/pom.xml#L137-L146

Add an scm section to the project POM. See https://github.com/bluedenim/log4j-s3-search/blob/master/appender-core/pom.xml#L147-L152

Configure Project for Nexus-Staging-Maven Plugin:

See https://github.com/bluedenim/log4j-s3-search/blob/master/appender-core/pom.xml#L95-L105

If using a different server ID than “ossrh,” keep in sync with the entries defined in the distributionManagement section and also the configuration in the Maven conf/settings.xml.

Configure project for Maven Release Plugin:

Add the Maven Release Plugin. See https://github.com/bluedenim/log4j-s3-search/blob/master/appender-core/pom.xml#L77-L94

Configure Project to Sign artifacts when releasing:

See https://github.com/bluedenim/log4j-s3-search/blob/master/appender-core/pom.xml#L154-L180

Preparation of Release:

Finally, to prepare for a project to be released,

  • Build the project once with mvn install
  • Fix all the issues that come up with unit tests and Javadoc.
  • Commit and push all the changes to GitHub.
  • Modify the project’s version to be a “-SNAPSHOT” release for the release I want to make. For example, if I want to release a 1.0.0 version, use the version “1.0.0-SNAPSHOT” for the project. However, none of the project’s dependencies can be to SNAPSHOT versions.
  • Commit the change. No need to push to GitHub.

Run mvn release:prepare

The process will ask some questions. The release will be “1.0.0” in this example. The next release is probably “1.0.1-SNAPSHOT” as suggested, but this can always be modified later as needed.

Release TO SONATYPE:

Run mvn release:perform

This takes a while, and it will actually push artifacts to Sonatype’s servers. Things can go wrong here that range from intermittent network errors to errors with the setup of the repo.

Artifacts can be verified by logging into https://oss.sonatype.org/ with the Sonatype account created earlier and searching for the released artifacts.

Issues may need to be filed with Sonatype if the repo is set up incompletely. Even when things work correctly, it may take some time for things to propagate through the various servers before the artifacts show up in mvnrepository.com.

Once this works the first time, subsequent releases are more stable.

 

Addendum:

Parent POMs

To release parent POMs w/o triggering releasing the modules under the parent, add:

 -N -Darguments=-N

as documented here: http://maven.apache.org/maven-release/maven-release-plugin/faq.html#nonrecursive