How to Release jar Package to the Maven Central Repository

How to Release jar Package to the Maven Central Repository

·

0 min read

The Maven Central Repository does not support uploading jar packages directly, so you need to release them to some designated third-party Maven repositories, such as the Sonatype OSSRH repository, and then synchronize the jar packages to Maven through this repository. This article details the entire release, synchronization process.

Create a Sonatype Account

Click here to create an Sonatype account. Sonatype uses JIRA, a project management software provided by Atlassian, to manage the OSSRH repository.

Creating a New Project Issue to Release Components

The first step to commit a “component release request” is to create an issue on the JIRA Dashborad. Click the Createbutton shown is the picture:

Choose/type the project you want to create. Then choose an Issue Type. Put your Group ID in the summary and groupId fields.

Please be very careful with the Group ID which generally comes with a domain, because it will affect other components. Here we use domain com.vesoft.

Sonatype requests domain verification, so please verify via one of the following methods:

  • Add a JIRA number record to your DNS
  • Setup a redirect to your Github page

If you do not have any domains, please refer to this link: http://central.sonatype.org/pages/choosing-your-coordinates.html

  • Choose a Group ID with project hosting information, such as io.github.facebook or com.github.facebook
  • Another recommended way is to use the free managed security reporting services: Use https://hackerone.com/central-security-project/reports/new as the security protection of your project. Then the Sonatype staffs will take care the left things for you.

Waiting for Someone From Sonatype to Reply

It will take some time to review the issue due to the time difference. If your issue is approved, you will receive an email notification and a comment from the Sonatype staff under your issue. The comment looks like the following:

Use GPG to Create Key

Creating a GPG Key

> gpg --gen-key</span>

Select the encryption method:

  • RSA and RSA (default)
  • DSA and Elgamal
  • DSA (sign only)
  • RSA (sign only)

The first is selected by default. After selection, you need to enter the user name, email address, and Passphase, it’s equivalent to the keystore password.

View Public Key

> gpg --list-keys

xxx/.gnupg/pubring.gpg
---------------------------------
pub   2048R/xxxx 2019-12-02
uid   $YOUR_UID <$YOUR_EMAIL>
sub   2048R/**** 2019-12-02</span>

The public key ID is XXXXXX. You will use it soon.

Upload the Public Key to the PGP Key Server

gpg --keyserver hkp://keys.gnupg.net:11371 --send-keys xxxx</span>

Check if the upload is successful.

gpg: requesting key BB7576AC from certserver.pgp.com ...
gpg: key BB7576AC: 1 new signature

gpg: Total number processed: 1
gpg:         new signatures: 1
ASWE

alice> gpg --keyserver certserver.pgp.com --send-key blake@cyb.org</span><span id="855a" class="jf hl di ay in b em jw jx jy jz ka ju r jv">gpg: success sending to 'certserver.pgp.com' (status=200)</span>

NOTE:

  • Fill in the public key ID based on your situation
  • Key server pool.sks-keyservers.net does not works well due to the failure in verification and the obtainment. Maven supports two key servers: http://keys.gnupg.net:11371 and http://pool.sks-keyservers.net:11371
  • We use hkp protocol instead of HTTP protocol
  • You also need to add the port number

The local private key is used to digitally sign the uploaded component, and the user downloading the component can verify the signature through the uploaded public key. It is necessary to verify whether the component was uploaded by the account holder himself, because there is a possibility that the component can be modified.

Modify the Maven Configuration Files

Modify the Maven Configuration File. To modify Maven, you need to modify the setting.xml file and the pom.xml file of your project.

Configure the setting. xml File

Modify the ~/.m2/setting.xml file.

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                      http://maven.apache.org/xsd/settings-1.0.0.xsd">
    <servers>
      ...
        <server>
            <id>snapshots</id>
            <username>$USER_NAME</username>
            <password>$YOUR_PASSWORD</password>
        </server>
        <server>
            <id>release</id>
            <username>$USER_NAME</username>
            <password>$YOUR_PASSWORD</password>
        </server>
    </servers>

</settings></span>

Replace the USER_NAME and YOUR_PASSWORD to your own Sonatype user name and password. You will use the ID here in the pom.xml file.

Configure the pom. xml File

<project>
    ...

    <!-- More Project Information -->
    <name>nebula-java</name>
    <description>Nebula Java Client</description>
    <url>https://github.com/vesoft-inc/nebula-java</url>
    <scm>
        <connection>scm:git:https://github.com/vesoft-inc/nebula</connection>
        <url>https://github.com/vesoft-inc/nebula</url>
        <developerConnection>scm:git:https://github.com/vesoft-inc/nebula</developerConnection>
    </scm>
    <licenses>
        <license>
            <name>Apache License, Version 2.0</name>
            <url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
            <distribution>repo</distribution>
            <comments>license</comments>
        </license>
    </licenses>

    ...
    <profiles>
        <profile>
            <id>release</id>
            <build>
                <plugins>
                    <!-- Source -->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-source-plugin</artifactId>
                        <executions>
                            <execution>
                                <id>attach-sources</id>
                                <goals>
                                    <goal>jar</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                    <!-- Javadoc -->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-javadoc-plugin</artifactId>
                        <version>3.1.1</version>
                        <configuration>
                            <excludePackageNames>com.facebook.thrift:com.facebook.thrift.*</excludePackageNames>
                        </configuration>
                        <executions>
                            <execution>
                                <id>attach-javadocs</id>
                                <phase>package</phase>
                                <goals>
                                    <goal>jar</goal>
                                </goals>
                                <configuration>
                                    <doclint>none</doclint>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                    <!-- GPG -->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-gpg-plugin</artifactId>
                        <version>1.6</version>
                        <executions>
                            <execution>
                                <phase>verify</phase>
                                <goals>
                                    <goal>sign</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
            <distributionManagement>
                <repository>
                    <id>release</id>
                    <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
                </repository>
                <snapshotRepository>
                    <id>snapshots</id>
                    <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
                </snapshotRepository>
            </distributionManagement>
        </profile>
    </profiles>
    ...
</project></span>
  • The pom.xml file must include basic information like: name, description, url, licenses, developers, scm
  • To publish maven, you must have a documentation package and a source package in addition to the jar.Therefore, pom needs to add maven-javadoc-plugin and maven-source-plugin. For example:
com-vesoft-client
|-- pom.xml
|-- src\
`-- target
    `-- attach-source-javadoc-1.0-SNAPSHOT.jar
    `-- attach-source-javadoc-1.0-SNAPSHOT-javadoc.jar
    `-- attach-source-javadoc-1.0-SNAPSHOT-sources.jar</span>
  • The release and building request key encryption, so pom needs to add the maven-gpg-plugin.

Multi-Module Project Configuration

nebula-java is a multi-module project.

<modules>
    <module>client</module>
    <module>examples</module>
</modules></span>

To upload Client, please upload the parent pom.xl or the Client cannot find the dependencies. However, we don't want to upload the examples module thus making the following changes:

  • Project information like name, description, url, licenses, developers, scm and maven-gpg-plugin are placed in the parent's pom.xml file.
<project>
  ...
    <name>nebula-java</name>
    <description>Nebula Java Client</description>
    <url>https://github.com/vesoft-inc/nebula-java</url>
    <scm>
        <connection>scm:git:https://github.com/vesoft-inc/nebula</connection>
        <url>https://github.com/vesoft-inc/nebula</url>
        <developerConnection>scm:git:https://github.com/vesoft-inc/nebula</developerConnection>
    </scm>
    <licenses>
        <license>
            <name>Apache License, Version 2.0</name>
            <url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
            <distribution>repo</distribution>
            <comments>license</comments>
        </license>
    </licenses>

    <developers>
        <developer>
            <id>$ID</id>
            <name>$NAME</name>
            <email>$EMAIL</email>
            <organization>vesoft</organization>
            <roles>
                <role>architect</role>
                <role>developer</role>
            </roles>
        </developer>
    </developers>

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

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-gpg-plugin</artifactId>
                <version>1.6</version>
                <executions>
                    <execution>
                        <phase>verify</phase>
                        <goals>
                            <goal>sign</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
  </project></span>
  • Add maven-javadoc-plugin, maven-source-plugin and maven-deploy-plugin in Java Client's pom.xml file.
<plugins>
  ......
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-source-plugin</artifactId>
        <executions>
            <execution>
                <id>attach-sources</id>
                <goals>
                    <goal>jar</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-javadoc-plugin</artifactId>
        <version>3.1.1</version>
        <configuration>
            <excludePackageNames>com.facebook.thrift:com.facebook.thrift.*</excludePackageNames>
        </configuration>
        <executions>
            <execution>
                <id>attach-javadocs</id>
                <phase>package</phase>
                <goals>
                    <goal>jar</goal>
                </goals>
                <configuration>
                    <doclint>none</doclint>
                </configuration>
            </execution>
        </executions>
    </plugin>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-deploy-plugin</artifactId>
        <executions>
            <execution>
                <id>default-deploy</id>
                <phase>deploy</phase>
            </execution>
        </executions>
    </plugin>
</plugins></span>

Declare skip deploy in example module’s pom.xml file.

<plugins>
  ......
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-deploy-plugin</artifactId>
        <configuration>
            <skip>true</skip>
        </configuration>
    </plugin>
</plugins></span>

Q: Why is maven-gpg-plugin placed in the parent's pom.xml, while

maven-javadoc-plugin and maven-source-plugin plugins are placed in the client's pom.xml?

A: Because all the uploaded components need to be encrypted, including the parent’s pom.xml; and only the client needs to upload javadoc and source, so maven-javadoc-plugin and maven-source-plugin plugins are put in Client.

Upload Components to the OSS Cloud

Run the following command in the nebula-java/ directory:

> mvn clean deploy -DpomFile=pom.xml</span>

NOTE: If you do not add -DpomFile, there will be no _pom.xml_ of parent in the uploaded file.

Publish Components in the OSS Cloud

Sign in https://oss.sonatype.org/#stagingRepositories with your Sonatype account to check the uploaded components. They are currently placed in the Staging repository. You can perform fuzzy searches to locate the components you uploaded.

At this moment, the status of the component is open, choose it then click the close button. The system will automatically verify wether the component meets the requested needs. (Happy persons are all alike, every unhappy person is unhappy in his own way. You may encounter with various errors, so good luck!)

When the verification is done, the status turns to Closed.

Finally, click Release to release the component.

Notifying Sonatype That the Components Have Been Published Successfully

Add a comment under the JIRA issue mentioned above to inform the Sonatype staffs that the components are released successfully so they can review them. Once released, the issue will be closed.

Waiting for Component Approval

You just wait for the approval.

Search for Components From the Central Warehouse

After about ten minutes, you can find the newly released component here https://repo1.maven.org/maven2, which can be used directly in the pom.xml file. ~~ 👏👏

Your central repository (link: http://search.maven.org/) becomes accessible after the synchronization is completed in about 2 hours.

Once you have successfully released the components for the first time. You don’t need to bother to repeat the whole process again, rather, you can use the Group ID directly to implement new releases.

New Release Guide

Process on releasing components with the same Group ID:

  • Edit the settings.xml file and the pom.xml file according to the preceding session;
  • Upload Your Deployment;
  • Close and release the components at https://oss.sonatype.org/;
  • Wait for the sync (about 2 hours)

Tips: Modification and deletion are not supported in the published releases.

GitHub Repository

More details on Nebula Graph please refer to our GitHub Repository. We appreciate your issues or pull requests. If you like us, please give us a star.