How to Deploy the Artifacts of a Project to Sonatype Nexus, with Maven

January 03, 2018 By Eugen Paraschiv

14 minute read time

Editor's Note: This article is a contribution from one of our community members. If you have questions or feedback, please continue the discussion in the comments section below.

Overview

In a previous article, I discussed how a Maven project can install locally a third party jar that has not yet been deployed on Maven Central (or on any of the other large and publicly hosted repositories).

That solution should only be applied in small projects where installing, running and maintaining a full Sonatype Nexus Repository server may be overkill. However, as a project grows, Sonatype Nexus quickly becomes the only real and mature option for hosting third party artifacts, as well as for reusing internal artifacts across development streams.

This article will show how to deploy the artifacts of a project to Sonatype Nexus Repository OSS, with Maven.

Sonatype Nexus Requirements in the pom.xml

In order for Maven to be able to deploy the artifacts it creates in the package phase of the build, it needs to define the repository information where the packaged artifacts will be deployed, via the distributionManagement element:

1
2
3
4
5
6
<distributionManagement>
   <snapshotRepository>
      <id>nexus-snapshots</id>
   </snapshotRepository>
</distributionManagement>

A hosted, public Snapshots repository comes out of the box on Sonatype Nexus, so there’s no need to create or configure anything further. Sonatype Nexus makes it easy to determine the URLs of its hosted repositories – each repository displays the exact entry to be added in the <distributionManagement> of the project pom, under the Summary tab.

Plugins

By default, Maven handles the deployment mechanism via the maven-deploy-plugin – this mapped to the deployment phase of the default Maven lifecycle:

1
2
3
4
5
6
7
8
9
10
11
12
13
<plugin>
   <artifactId>maven-deploy-plugin</artifactId>
   <version>2.8.1</version>
   <executions>
      <execution>
         <id>default-deploy</id>
         <phase>deploy</phase>
         <goals>
            <goal>deploy</goal>
         </goals>
      </execution>
   </executions>
</plugin>

The maven-deploy-plugin is a viable option to handle the task of deploying to artifacts of a project to Sonatype Nexus, but it was not built to take full advantage of what Sonatype Nexus has to offer. Because of that fact, we built a Sonatype Nexus specific plugin – the nexus-staging-maven-plugin – that is actually designed to take full advantage of the more advanced functionality that Sonatype Nexus has to offer – functionality such as staging.

Although for a simple deployment process we do not require staging functionality, we will go forward with this custom Sonatype Nexus plugin since it was built with the clear purpose to talk to Sonatype Nexus well.

The only reason to use the maven-deploy-plugin is to keep open the option of using an alternative to Sonatype Nexus in the future. However, unlike other components that may actually change throughout the lifecycle of a project, the Maven Repository Manager is highly unlikely to change, so that flexibility is not required.

So, the first step in using another deployment plugin in the deploy phase is to disable the existing, default mapping:

1
2
3
4
5
6
7
8
<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-deploy-plugin</artifactId>
   <version>${maven-deploy-plugin.version}</version>
   <configuration>
      <skip>true</skip>
   </configuration>
</plugin>

Now, we can define:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<plugin>
   <groupId>org.sonatype.plugins</groupId>
   <artifactId>nexus-staging-maven-plugin</artifactId>
   <version>1.5.1</version>
   <executions>
      <execution>
         <id>default-deploy</id>
         <phase>deploy</phase>
         <goals>
            <goal>deploy</goal>
         </goals>
      </execution>
   </executions>
   <configuration>
      <serverId>nexus</serverId>
      <nexusUrl>http://localhost:8081/nexus/</nexusUrl>
      <skipStaging>true</skipStaging>
   </configuration>
</plugin>

The deploy goal of the plugin is mapped to the deploy phase of the Maven build.

Also notice that, as discussed, we do not need staging functionality in a simple deployment of -SNAPSHOT artifacts to Sonatype Nexus, so that is fully disabled via the <skipStaging> element.

The Global settings.xml

Deployment to Sonatype Nexus Repository is a secured operation – and a deployment user exists for this purpose out of the box on any Sonatype Nexus instance.

Configuring Maven with the credentials of this deployment user, so that it can interact correctly with Sonatype Nexus, cannot be done in the pom.xml of the project. This is because the syntax of the pom doesn’t allow it, not to mention the fact that the pom may be a public artifact, so not well suited to hold credential information.

The credentials of the server have to be defined in the global Maven setting.xml:

1
2
3
4
5
6
7
<servers>
   <server>
      <id>nexus-snapshots</id>
      <username>deployment</username>
      <password>the_pass_for_the_deployment_user</password>
   </server>
</servers>

The server can also be configured to use key based security instead of raw and plaintext credentials.

The Deployment Process

Performing the deployment process is a simple task:

1
mvn clean deploy -Dmaven.test.skip=true

Skipping tests is OK in the context of a deployment job because this job should be the last job from a deployment pipeline for the project.

A common example of such a deployment pipeline would be a succession of Jenkins jobs, each triggering the next only if it completes successfully. As such, it is the responsibility of the previous jobs in the pipeline to run all tests suites from the project – by the time the deployment job runs, all tests should already pass.

If ran a single command, then tests can be kept active to run before the deployment phase executes:

mvn clean deploy

Conclusion

This is a simple, yet highly effective solution to deploying to Maven artifacts to Sonatype Nexus Repository.

It is also somewhat opinionated – nexus-staging-maven-plugin is used instead of the default maven-deploy-plugin; staging functionality is disabled, etc – it is these choices that make the solution simple and practical.

Tags: Sonatype Nexus, spring, Everything Open Source, Maven, REST API, Sonatype Nexus Repository

Written by Eugen Paraschiv

I'm an engineer with a math background and a passion for building things on the web. I love to help teams build better, more secure web applications with Spring, primarily through video. You can follow my work at http://www.baeldung.com/