by Seun Matt

How to Upload an Open-Source Java Library to Maven Central

vkpmwy8oSVeopuE86popOytHNCIbpsoiWUla

This article is a comprehensive guide, from start to finish, on how to deploy a Java library to Maven Central so everyone can use it by including the dependency in their project(s).

It goes without saying that there has to be a Java library for it to be uploaded. Hence, the first thing is creating a Java library that’s unique, of quality code standard, and that will be beneficial to the developer community. Of course, you’ve got that already — that’s why you’re reading this after all (or maybe you’re planning on creating one).

In summary, to upload a shiny new Java library to Maven Central, we’ll have to reserve our Group ID, provide the required details in the project’s pom.xml, sign the generated artifacts with GnuPG and, finally, deploy to Sonatype’s Nexus Repository Manager.

STEP ONE:

The first step is for us to make sure our open-source library is available on a publicly accessible code repository like Github. Then we can proceed to reserve our desired Group ID. The Group ID should ideally be unique to an individual or organization — as in a domain. Examples of Group ID includes com.smattme and org.apache.commons.

So, we are going to create a JIRA account here and then log in to create a new project ticket. Clicking on the create button at the top of the website will load a modal where we’ll supply the Group ID (e.g. com.smattme), SCM URL (e.g. https://github.com/SeunMatt/mysql-backup4j.git), project URL (e.g. https://github.com/SeunMatt/mysql-backup4j), Summary (which can be the name of the library like mysql-backup4j) and finally project description.

NOTE: In the modal for creating a new project ticket, ensure the Project field is set to Community Support — Open Source Project Repository Hosting (OSSRH) and the Issue Type is New Project.

The creation of the new ticket project will trigger the creation of repositories on Sonatype’s OSS Repository Hosting (OSSRH) that’ll be synced to Maven Central after deploying our artifacts.

It’s important not to deploy until there’s an email confirmation that the issue created has been resolved. If there’s any problem along the line, we can always comment on the issue to get help and/or explanation.

STEP TWO:

Now that we’ve successfully registered our Group ID, the next thing to do is update the project’s pom.xml with the necessary information. Let’s start by providing the project’s name, description and URL as well as the coordinates and packaging information:

<groupId>com.smattme</groupId>
<artifactId>mysql-backup4j</artifactId>
<version>1.0.1</version>
<packaging>jar</packaging> 
<name>${project.groupId}:${project.artifactId}&lt;/name> 
<description> This is a simple library for backing up mysql databases and sending to emails, cloud storage and so on. It also provide a method for programmatically, importing SQL queries generated during the export process</description> 
<url>https://github.com/SeunMatt/mysql-backup4j</url>

Up next is the license and developers information. In this case, we’ll be using an MIT license. If any other license is used, all that’s needed is a corresponding URL to such license. If it’s an open-source license, there’s a good chance it’s going to be available on opensource.org:

<licenses> <license>  <name>MIT License</name>              <url>http://www.opensource.org/licenses/mit-license.php</url>       <;/license> </licenses> <developers> 
 <developer>   <name>Seun Matt</name>   <email>smatt382@gmail.com</email>      <organization>SmattMe</organization> <organizationUrl>https://smattme.com</organizationUrl></developer> 
</developers>

Another important piece of information required is the source code management (SCM) details:

<scm>   <connection>scm:git:git://github.com/SeunMatt/mysql-backup4j.git</connection>   <developerConnection>scm:git:ssh://github.com:SeunMatt/mysql-backup4j.git</developerConnection>   <url>https://github.com/SeunMatt/mysql-backup4j/tree/master</url> </scm>

In this case, the project is hosted on Github, thus the reason for the supplied values. Example configurations for other SCM can be found here.

STEP THREE:

In this step, we’ll be configuring our project for deployment to the OSSRH using the Apache Maven Plugin. The plugin requires that we add a distributionManagement section to our pom.xml:

<distributionManagement> 
  <snapshotRepository>   <id>ossrh</id>        <url>https://oss.sonatype.org/content/repositories/snapshots</url> </snapshotRepository> 
<repository> <id>ossrh</id> <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url> </repository> 
</distributionManagement>

We’ll supply the user credentials for the configured repositories above by adding a <servers> entry to settings.xml which can be found in the user’s home directory e.g. /Users/smatt/.m2. Note that the id is the same as that of the snapshotRepository and repository configured above:

<settings>   <servers>    <server>     <id>ossrh</id>    <username>your-jira-id</username>    <password>your-jira-pwd&lt;/password>  </server>   </servers></settings>

The next thing is for us to add some Maven build plugins: source-code, Javadoc, nexus staging and the GPG plugins. Each of these plugins will be placed within the <plugins> tag that’s inside the &lt;build> tag.

Deploying a library to OSSRH requires that the source code and JavaDoc of the library be deployed as well. Hence, we’ll add the Maven plugins to achieve that seamlessly:

<plugin>   <groupId>org.apache.maven.plugins</groupId>  <artifactId>maven-javadoc-plugin</artifactId>         <version>3.0.0</version> <executions>   <execution>    <id>attach-javadocs</id>   <goals>     <goal>jar</goal>   </goals>   </execution>  </executions> </plugin> 
<plugin>  <groupId>org.apache.maven.plugins</groupId>  <artifactId>maven-source-plugin</artifactId>    <version>3.0.1</version> <executions>   <execution>    <id>attach-sources</id>   <goals>      <goal>jar</goal>   </goals>   </execution> </executions> </plugin>

The latest version of the Javadoc and Source code plugins can be found here and here respectively.

Another requirement we need to satisfy is the signing of our artifacts with a GPG/PGP program. For that, we have to install GnuPG on our system. After downloading and installation, we can always run gpg — version to verify the installation. Note that on some systems gpg2 — version will be used. Also, we should ensure that the bin folder of the GnuPG installation is in the system path.

Now we can generate a key pair for our system by running the command gpg — gen-key and following the prompts. We can list the keys that are available using gpg — list-keys. It’s important to follow this guide to ensure the primary key generated is used to sign our files.

Let’s get back to our pom.xml file and add the Maven plugin for the GnuPG program so our files can be automatically signed with the default key we generate during program build:

<plugin>  <groupId>org.apache.maven.plugins</groupId>  <artifactId>maven-gpg-plugin</artifactId>  <version>1.6</version>  <executions>  <execution>    <id>sign-artifacts</id>   <phase>verify</phase>   <goals>     <goal>sign</goal>   </goals> </execution> </executions> </plugin>

The latest version for the Maven GPG plugin can be found here. While generating our key pair, we provided a passphrase for it; that passphrase is going to be configured in our .m2/settings.xml file. We can also specify the executable for our GnuPG program — either gpg or gpg2. So in the settings.xml file, we’ll add a &lt;profiles> section just after the closing tag for </servers>:

<profiles>  <profile>   <id>ossrh</id>  <activation>   <activeByDefault>true</activeByDefault>  </activation>  <properties>    <gpg.executable>gpg</gpg.executable>   <gpg.passphrase>pass-phrase</gpg.passphrase> </properties> </profile> </profiles>

To wrap it all up, we’ll add the Nexus Staging Maven plugin so that we can deploy our library — including the source code, Javadoc and *.asc files to OSSRH, with simple commands:

<plugin>  <groupId>org.sonatype.plugins</groupId> <artifactId>nexus-staging-maven-plugin</artifactId>          <version>1.6.8</version> <extensions>true</extensions>
 <configuration>    <serverId>ossrh</serverId>    <nexusUrl>https://oss.sonatype.org/</nexusUrl> <autoReleaseAfterClose>false</autoReleaseAfterClose> </configuration>
</plugin>

The latest version of the plugin can be found here. Take note of the <serverId>ossrh</serverId>; You’ll notice the same value ossrh is used in the settings.xml file. This is important for the plugin to be able to locate the credentials we configured in the <servers> section of settings.xml.

STEP FOUR:

In this section we’ll run some Maven CLI commands to do the actual deployment. Before this stage, it’s just so right that we double check and test the library to make sure there’re no bugs. Why? We’re about to go live!

To start with run: mvn clean deploy

If everything goes well, we’ll see, among the console outputs, the staging repository id created for the project like this:

* Created staging repository with ID “comsmattme-1001”.

NOTE: “comsmattme” is the Group ID we’ve been using in this article as an example.

Let’s log in to https://oss.sonatype.org with the same credentials for the JIRA account created earlier to inspect the artifacts we’ve deployed to staging. After login, we’ll click on Staging Repositories on the left side menu under the Build Promotion sub-menu and using the search bar at the top right of the page, we’ll search for the staging repository ID created e.g. comsmattme-1001 in this case.

We should be able to see and inspect the artifacts that were uploaded by the nexus staging Maven plugin. If satisfied with everything, then we can do a release by running this maven command:

mvn nexus-staging:release

It may take up to 2 hours or more for the library to show up on Maven Central Search. To search for our artifact, we’ll supply the following query to the search box: g:com.smattme a:mysql-backup4j where g is the group ID and a is the artifact name.

Conclusion

In this comprehensive article, we’ve walked through the process of deploying our Java library to Maven Central. The complete pom.xml for the example project used in this article can be found here and the settings.xml can be found here as well. Happy coding!

Originally published at smattme.com.