So you think you're ready to run with the big boys and deploy an artifact to Maven Central?

Well here's some good news: if you're an experienced developer, it ain't that hard.

But it will take some time.

In this guide, I'll show you how to do it.

The Prerequisites

First, you're going to need a Maven project that's ready for sharing.

If you don't have that, stop reading now because you clearly landed on the wrong article from whichever search engine brought you here. Try a different search term.

But even if you do have a Maven project handy, please note the "ready for sharing" part above. You don't want to publish lame code.

However, you don't have to publish only release-worthy stuff. You can publish snapshots as well.

But there's another prereq that you might not know about.

You need a domain name.

In case you're skimming the article you might have been tempted to zip past this section because you think you have all the prerequisites.

But if you don't have a domain name, you're up the creek.

Sure, you can use something like io.github.xxx for your Group ID. But you won't come across as a professional if you go that route.

It's best to grab your own domain name. Obviously, mine is careydevelopment.us.

So my Group IDs all begin with us.careydevelopment. You know how this works by now.

The next prereq: you need a license, Bo.

Yes. You're in the Big League now. That means your software needs a license.

Fortunately, you can select a boilerplate license if you're storing your code in GitHub. Just click on the Add File button at the very top of your repo. 

Then, select Create a New FIle from the dropdown that appears. When you're asked for a file name, enter LICENSE.

At that point, GitHub will give you an option to choose a license template. 

Now it's up to you and your lawyer. You can follow GitHub's advice and opt for the MIT License. But you really need to talk to someone who knows the law before you make a decision.

Once you've created your license, merge your new branch with main/master.

Now you have a license. You'll need that later.

Another prereq: you'll need an account on Sonatype Jira. Just click that link and get signed up if you don't already have an account.

The next prereq deserves a section all to itself.

Get Up and Running With PGP

The folks at Sonatype (that's the organization that houses the Maven Central repository) will insit that you sign the artifact.

As in: with a digital signature.

And you'll do that with an encryption system called PGP (which stands for Pretty Good Privacy).

Now the PGP solution you'll likely pick to make this happen is called GPG. 

No. That's not a typo.

GPG stands for GnuPG or the Gnu Privacy Guard.

So you'll use GPG to sign your artifact with PGP.

I don't make the rules, folks. I just report on what's out there.

Anyhoo, get the ball rolling with GnuPG by downloading it and installing it on whichever system you'll use to sign the artifact. That will be the same system you use to build the artifact, by the way.

Once you've installed GPG, generate a key pair with the following command:

gpg --gen-key

You'll have to answer some questions.

This is one situation where you don't want to accept all the defaults.

However, you can accept the defaults when asked about the kind (RSA) and size (2048 bit).

But when it comes to the validity time, don't set it never expire. Instead, set it to expire at some point in the future not more than two years hence.

I know you might be tempted to go with a never-ending key, but resist that temptation. You can always extend the key later on.

Next, provide your name, email, and a comment for the key. Just keep in mind: anyone downloading your artifact can see that info. So you're exposed.

And then enter a passphrase for the key. Follow the usual rules for airtight passphrases. 

Just make sure you keep your passphrase safe and handy. You'll need it again.

By the way, if you're on a Linux system that seems to hang while generating the key, just log in to your server in another shell and enter this at the command line:

dd if=/dev/sda of=/dev/zero

Then wait a bit and GPG should complete the key generation process.

Now type this at the command line:

gpg2 --list-keys

That should list your keys. You'll see output like this:

/home/dude/.gnupg/pubring.gpg
------------------------------
pub   1024D/D7EBD57A 2021-01-13
uid                  Brian Carey (Who's Cool)
sub   2048g/E754445C 2021-01-13

Well that's a good sign.

Now, pay attention to that D7EBD57A in the first pub line. That's the keyid and you're going to need it in a moment.

And if you type this:

gpg2 --list-secret-keys

You'll see the private keys in a similar fashion.

Next, distribute your keys to public key servers. Here's an example of how to do that:

gpg2 --keyserver hkp://pool.sks-keyservers.net --send-keys D7EBD57A

Pay attention to the keyid at the end. That should match the keyid you saw when you listed your public keys.

Now what's going on with this: hkp://pool.sks-keyservers.net?

Well for starters that hkp:// bit is the protocol that you'll use to transfer your keys. I don't think you'll likely use it for any other purpose than what you're doing here.

And pool.sks-keyservers.net is the name of the key server.

You'll probably need to distribute the key to other servers if you're in a hurry. But I'm told that, after a while, the public key servers get in sync.

Don't worry if you don't have your key on all the right servers. When you try to deploy your artifact to Maven Central, the deployment process will be kind enough to tell you exactly which servers still need your key.

Then, you can manually deploy your key to those servers and reattempt your deployment.

Wait... Wasn't This About Maven?

Believe it or not, that whole section on PGP/GPG was necessary if you want to deploy an artifact to Maven Central.

You can't skip it.

You need to follow those instructions.

Trust me.

So if you skipped or skimmed that section, go back and follow the steps. 

And once you're done with that, you can work on your POM file.

Start by adding a section for the license.

    <licenses>
        <license>
            <name>MIT License</name>
            <url>https://github.com/careydevelopment/activities/blob/main/LICENSE</url>
        </license>
    </licenses>

Put that right below the <build> section in your POM file.

By the way: if you want to know where everything "belongs" in a POM file, check this out. Look in the Quick Overview section.

But back to this: make sure you change the XML above to reflect your license name and its location. 

Next, add the name of your developer. That's probably you:

    <developers>
        <developer>
            <id>brianmcarey</id>
            <name>Brian Carey</name>
        </developer>
    </developers>

Put that block just below the <license> stanza you just created. Just make sure, once again, that you change the element values.

Cuz you're not me.

That <id> element value, by the way, needs to reflect your username on Sonatype. Getting an account set up there was one of the prereqs, as you may recall.

Next, tell Sonatype a little bit about your source repo:

    <scm>
        <connection>scm:git:git@github.com:careydevelopment/activities.git</connection>
        <developerConnection>scm:git:ssh://github.com:careydevelopment/activities.git</developerConnection>
        <url>https://github.com/careydevelopment/activities</url>
    </scm>

That one goes just below the <developers> block that you just created.

And yeah: change the element values to reflect your own stuff. Yadda yadda yadda.

Then set up the distribution management:

    <distributionManagement>
        <snapshotRepository>
            <id>ossrh</id>
            <url>https://s01.oss.sonatype.org/content/repositories/snapshots</url>
        </snapshotRepository>
    </distributionManagement>  

This time you don't have to worry about changing any values. You can copy and paste that as-is.

That stanza goes right below the <scm> stanza. It will likely be the last thing you see in your POM file before </project>.

Now let's get the build process situated.

If You Build It, They Will Come

Next, you need to update the <build> stanza. You likely already have some stuff in there, but this is what you'll need if you're interested in deploying anything to Maven Central.

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.2.0</version>
            </plugin>
            <plugin>
                <groupId>org.sonatype.plugins</groupId>
                <artifactId>nexus-staging-maven-plugin</artifactId>
                <version>1.6.7</version>
                <extensions>true</extensions>
                <configuration>
                    <serverId>ossrh</serverId>
                    <nexusUrl>https://s01.oss.sonatype.org/</nexusUrl>
                    <autoReleaseAfterClose>true</autoReleaseAfterClose>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-gpg-plugin</artifactId>
                <version>1.5</version>
                <executions>
                    <execution>
                        <id>sign-artifacts</id>
                        <phase>verify</phase>
                        <goals>
                            <goal>sign</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <version>2.2.1</version>
                <executions>
                    <execution>
                        <id>attach-sources</id>
                        <goals>
                            <goal>jar-no-fork</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-javadoc-plugin</artifactId>
                <configuration>
                    <source>11</source>
                    <detectJavaApiLink>false</detectJavaApiLink>
                </configuration>
                <version>2.9.1</version>
                <executions>
                    <execution>
                        <id>attach-javadocs</id>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
        <finalName>${project.artifactId}</finalName>
    </build>

You're probably already working with that first plugin (maven-jar-plugin). That builds your JAR file.

The second plugin, nexus-staging-maven-plugin, controls the Nexus staging workflow.

So let me explain Nexus: that's the repository manager created by Sonatype.

While I'm explaining terminology, you'll also see OSS and OSSRH bandied about during this process.

OSS stands for Open Source Software. But when it's used in this context, it's Sonatype's Open Source Software Index. That's how you find cool JARs to include in your projects.

You can think of OSS as a library for software modules.

OSSRH stands for OSS Repository Hosting. It uses Nexus to offer service for open source artifacts. 

The next plugin, maven-gpg-plugin, handles the digital signature process. Just make sure GPG is available in whatever context you're using to deploy the artifact.

What I'm trying to say is: you might have trouble doing this with Jenkins. That's a subject I'll probably cover in a different guide.

The maven-source-plugin archives the source files for your project. That's okay because Maven Central is all about hosting open-source software. You shouldn't want to hide anything.

And, finally, the maven-javadoc-plugin creates the Javadocs for your project.

All those steps are necessary. If you leave out any one of those plugins, I think you'll find that you won't successfully deploy your artifact.

Ask for Permission

You're getting closer to finishing this process.

Next, head over to Sonatype and enter a Jira ticket. Use that ticket to request access for your Group ID.

Pro-tip: use the base Group ID. If the Group ID for your project is us.careydevelopment.models, just put us.careydevelopment in there. Then you can create projects with different extensions later on.

When you submit the ticket you'll likely get a form letter in your inbox asking you to verify ownership of the domain name that matches the Group ID.

You'll have to add a TXT record to your DNS with the Jira ticket ID. How you do that depends on whatever hosting provider you're using.

But it's not difficult.

Give it a day or two once you've submitted your request. Then, you should get a happy notification that your Group ID is approved and you can deploy artifacts to Maven Central.

But How?

So how do you actually deploy an artifact to Maven Central? It's easy.

Just visit the directory that houses the branch that you want to deploy. Then, at the command line, enter:

mvn clean deploy

Yep. That's it.

Let Maven do its magic and after a while you should get a message that your deployment was successful.

However, this being your first time, you might get a message that something went wrong.

Relax. That's normal.

Fortunately, Sonatype should give you a very detailed message about exactly what went wrong. You just need to take the appropriate steps to fix it.

When you finally succeed at deploying your artifact, hurry up and wait.

It might take as long as half an hour before that thing is visible in the index.

You can see my stuff here, by the way.

And you can also search for artifacts.

Anything else? Nah, I think we're pretty much done here.

Wrapping It Up

Whew! That's a lot of work just to get your artifact in Maven Central.

But once you do it for your first project, it's smooth sailing for everything else.

So take the time to get everything set up initially. Then, you can deploy as much as you want and as often as you want later on.

Have fun!

Photo by Rachel Xiao from Pexels