# Maven Repositories

Nexus Repository was designed to support the Maven repository format and it continues to include excellent support for users of Apache Maven, Apache Ant/Ivy, Eclipse Aether, Gradle, and others.

This section explains the default configuration for creating Maven repositories as well as searching and browsing the repositories. Build tool configuration for Apache Maven, Apache Ant, Gradle, and other tools follow.

## Maven Repository Format

[Apache Maven](http://maven.apache.org/) created the most widely used repository format in the Java development ecosystem with the release of Apache Maven 2. It is used by all newer versions of Apache Maven and many other tools including Apache Ivy, Gradle, sbt, Eclipse Aether, and Leiningen. Further information about the format can be found in [An Example - Maven Repository Format](https://help.sonatype.com/en/maven-repositories.html#maven-repository-format-162079-1 "Maven Repository Format").

The format is used by many publicly available repositories. The [Central Repository](http://central.sonatype.org/) is the largest repository of components aimed at Java/JVM-based development and beyond and is used the Maven repository format for release components of numerous open source projects. It is configured as a proxy repository by default in Apache Maven and widely used in other tools.

In addition to the generic repository management features documented in [Repository Management](https://help.sonatype.com/en/repository-management.html "Repository Management"), specifics of the Maven repository format can be configured for each repository in the _Maven 2_ section:

### Version Policy

| Option   | Details                                                                                                                                                                                                                     |
|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Release  | A Maven repository can be configured to be suitable for release components with the Release version policy. The Central Repository uses a release version policy.                                                          |
| Snapshot | Continuous development is typically performed with snapshot versions supported by the Snapshot version policy. These version values have to end with _-SNAPSHOT_ in the POM file. This allows repeated uploads where the actual number used is composed of a date/timestamp and an enumerator and the retrieval can still use the _-SNAPSHOT_ version string. The repository manager and client tools manage the metadata files that manage this translation from the snapshot version to the timestamp value. |
| Mixed    | The _Mixed_ version policy allows you to support both approaches within one repository.                                                                                                                                  |

### Layout Policy

The Maven repository format defines a directory structure as well as a naming convention for the files within the structure. Apache Maven follows these conventions. Other build tools, such as sbt, and custom tools have historically created usages that use the directory structure less strictly, violating the file naming conventions. Components based on these tools' different conventions have been published to public repositories, such as the Central Repository. These tools rely on these changed conventions.

| Option     | Details                                                                                                                                                                                                                      |
|------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Permissive | You can configure a layout policy of _Permissive_ to allow assets in the repository that violate the default format.                                                                                                                                             |
| Strict     | The default value of _Strict_ requires publishing and accessing tools to follow the Apache Maven conventions. This is the preferred setting if you are using Apache Maven, Eclipse Aether, and other strictly compatible tools.                |

### Content Disposition

| Option     | Details                                                                                                                                                                                                                      |
|------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Inline     | Indicates that repository content should be displayed to users within the browser. By default, new Maven repositories are assigned a Content-Disposition header of _Inline_.                                               |
| Attachment  | Indicates repository content should be provided as an attachment that a user downloads.                                                                                                                                                                                   |

## Proxying Maven Repositories

A default installation of Nexus Repository Manager includes a proxy repository configured to access the Central Repository via HTTPS using the URL `https://repo1.maven.org/maven2/`. To reduce duplicate downloads and improve download speeds for your developers and CI servers, you should proxy all other remote repositories you access as proxy repositories as well.

To proxy a Maven repository, you simply create a new repository using the recipe _maven2 (proxy)_ as documented in [Repository Management](https://help.sonatype.com/en/repository-management.html "Repository Management").

Minimal configuration steps are:

- Define _Name_
- Define URL for _Remote storage_ e.g. `https://repo1.maven.org/maven2/`
- Select a _Blob store_ for _Storage_

This creates a repository using the _Release_ version policy and a _Strict_ layout policy. Both can be configured as appropriate for the remote repository.

If the remote repository contains a mixture of release and snapshot versions, you have to set the version policy to _Mixed_.

Usage of the repository with build tools such as sbt, potentially requires the layout policy to be set to _Permissive_.

### Proxying the Oracle Maven Repository

Proxying the [Oracle Maven Repository](https://docs.oracle.com/middleware/1213/core/MAVEN/config_maven_repo.htm#MAVEN9010) requires special HTTP options for the _maven2 (proxy)_ recipe. Also, you must register for an account to access the external repository. Configure the proxy repository to access the Oracle repository, with these additional steps:

1. Add `https://maven.oracle.com` to the _Remote storage_ field.
2. Check _Authentication_, in the _HTTP_ section.
3. Enter the _Username_ and _Password_ from your Oracle account.
4. Check _HTTP request setting_s.
5. Check _Enable circular redirects_.
6. Check _Enable cookies_.

After applying these settings to your repository, data requests will be redirected to a queue of different URLs, most of which are involved with authentication. By enabling these options, you allow the repository manager to maintain the authentication state in a cookie that would be sent with each request, eliminating the need for the authentication-related redirects and avoiding timeouts.

## Hosting Maven Repositories

A hosted Maven repository can be used to deploy your own as well as third-party components. A default installation of Nexus Repository Manager includes two hosted Maven repositories. The _maven-releases_ repository uses a release version policy and the _maven-snapshots_ repository uses a snapshot version policy.

To create another hosted Maven repository, add a new repository with the recipe _maven2 (hosted)_ as documented in [Repository Management](https://help.sonatype.com/en/repository-management.html "Repository Management").

Minimal configuration steps are:

- Define _Name_
- Select _Blob store_ for _Storage_

## Grouping Maven Repositories

A repository group is the recommended way to expose all your Maven repositories from the repository manager to your users, without needing any further client side configuration. A repository group allows you to expose the aggregated content of multiple proxy and hosted repositories as well as other repository groups with one URL for tool configuration. This is possible for Maven repositories by creating a new repository with the _maven2 (group)_ recipe as documented in [Repository Management](https://help.sonatype.com/en/repository-management.html "Repository Management").

Minimal configuration steps are:

- Define _Name_
- Select _Blob store_ for _Storage_
- Add Maven repositories to the _Members_ list in the desired order

A typical, useful example is the _maven-public_ group that is configured by default. It aggregates the _maven-central_ proxy repository with the _maven-releases_ and _maven-snapshots_ hosted repositories. Using the URL of the repository group gives you access to the packages in all three repositories with one URL. Any new component added as well as any new repositories added to the group will automatically be available.

## Browsing and Searching Maven Repositories

You can browse Maven repositories in the user interface inspecting the components and assets and their details as documented in [Browsing Repositories and Repository Groups](https://help.sonatype.com/en/browsing-repositories.html "Browsing Repositories").

Components can be searched in the user interface as described in [Searching for Components](https://help.sonatype.com/en/searching-for-components.html "Searching for Components"). A search finds all components and assets that are currently stored in the repository manager, either because they have been deployed to a hosted repository or they have been proxied from an upstream repository and cached in the repository manager.

**Tip**  
You can change the default column order in the search and browse user interfaces to the familiar order of _Group_ (groupId), _Name_ (artifactId) and _Version_. Simply drag the _Group_ column from the middle to the left using the header. This setting will be persisted as your preference in your web browser.

## Configuring Apache Maven

To use repository manager with [Apache Maven](http://maven.apache.org/), configure Maven to check the repository manager instead of the default, built-in connection to the Central Repository.

To do this, you add a mirror configuration and override the default configuration for the central repository in your `~/.m2/settings.xml`, shown below:

**Configuring Maven to Use a Single Repository Group**

```
<settings>
  <mirrors>
    <mirror>
      <!--This sends everything else to /public -->
      <id>nexus</id>
      <mirrorOf>*</mirrorOf>
      <url>http://localhost:8081/repository/maven-public/</url>
    </mirror>
  </mirrors>
  <profiles>
    <profile>
      <id>nexus</id>
      <!--Enable snapshots for the built in central repo to direct -->
      <!--all requests to nexus via the mirror -->
      <repositories>
        <repository>
          <id>central</id>
          <url>http://central</url>
          <releases><enabled>true</enabled></releases>
          <snapshots><enabled>true</enabled></snapshots>
        </repository>
      </repositories>
      <pluginRepositories>
        <pluginRepository>
          <id>central</id>
          <url>http://central</url>
          <releases><enabled>true</enabled></releases>
          <snapshots><enabled>true</enabled></snapshots>
        </pluginRepository>
      </pluginRepositories>
    </profile>
  </profiles>
  <activeProfiles>
    <!--make the profile active all the time -->
    <activeProfile>nexus</activeProfile>
  </activeProfiles>
</settings>
```

In _Configuring Maven to Use a Single Repository Group_ a single profile called `nexus` is defined. It configures a `repository` and a `pluginRepository` with the id `central` that overrides the same repositories in the Super POM. The Super POM is internal to every Apache Maven install and establishes default values. These overrides are important since they change the repositories by enabling snapshots and replacing the URL with a bogus URL. This URL is overridden by the `mirror` setting in the same `settings.xml` file to point to the URL of your single repository group. This repository group can, therefore, contain release as well as snapshot components and Maven will pick them up.

The `mirrorOf` pattern of `*` causes any repository request to be redirected to this mirror and to your single repository group, which in the example is the public group.

It is possible to use other patterns in the mirrorOf field. A possible valuable setting is to use `external:*`. This matches all repositories except those using `localhost` or file based repositories. This is used in conjunction with a repository manager when you want to exclude redirecting repositories that are defined for integration testing. The integration test runs for Apache Maven itself require this setting.

More documentation about mirror settings can be found in the [mini guide on the Maven web site](http://maven.apache.org/guides/mini/guide-mirror-settings.html).

As a last configuration the `nexus` profile is listed as an active profile in the `activeProfiles` element.

Deployment to a repository is configured in the `pom.xml` for the respective project in the `distributionManagement` section. Using the default repositories of the repository manager:

```
<project>
...
<distributionManagement>
    <repository>
      <id>nexus</id>
      <name>Releases</name>
      <url>http://localhost:8081/repository/maven-releases</url>
    </repository>
    <snapshotRepository>
      <id>nexus</id>
      <name>Snapshot</name>
      <url>http://localhost:8081/repository/maven-snapshots</url>
    </snapshotRepository>
  </distributionManagement>
...
```

The credentials used for the deployment are found in the `server` section of your `settings.xml`. In the example below `server`contains `nexus` as the `id`, along with the default `username` and `password`:

```
<settings>
....
  <servers>
    <server>
      <id>nexus</id>
      <username>admin</username>
      <password>admin123</password>
    </server>
  </servers>
```

Full example projects can be found in the maven folder of the [example project](https://github.com/sonatype/nexus-book-examples) in the `nexus-3.x` branch. A full build of the `simple-project`, including downloading the declared dependencies and uploading the build output to the repository manager can be invoked with `mvn clean deploy`.

## Configuring Apache Ant and Apache Ivy

[Apache Ivy](http://ant.apache.org/ivy) is a dependency manager often used in Apache Ant builds. It supports the Maven repository format and can be configured to download dependencies that can be declared in the `ivy.xml` file. This configuration can be contained in the `ivysettings.xml`. A minimal example for resolving dependencies from a repository manager running on localhost is shown below:

**Minimal Ivy Configuration in an Ant file**

```
<ivysettings>
  <settings defaultResolver="nexus"/>
  <property name="nexus-public"
    value="http://localhost:8081/repository/maven-public/"/>
  <resolvers>
      <ibiblio name="nexus" m2compatible="true" root="${nexus-public}"/>
    </resolvers>
</ivysettings>
```

These minimal settings allow the `ivy:retrieve` task to download the declared dependencies.

To deploy build outputs to a repository with the ivy:publish task, user credentials and the URL of the target repository have to be added to `ivysettings.xml` and the `makepom` and `publish` tasks have to be configured and invoked.

Full example projects can be found in the `ant-ivy` folder of the [example project](https://github.com/sonatype/nexus-book-examples/tree/nexus-3.x) in the `nexus-3.x` branch. A full build of the `simple-project`, including downloading the declared dependencies and uploading the build output to the repository manager can be invoked with:

```
cd ant-ivy/simple-project
ant deploy
```

## Configuring Apache Ant and Eclipse Aether

[Eclipse Aether](https://projects.eclipse.org/projects/technology.aether) is the dependency management component used in Apache Maven 3+. The project provides Ant tasks that can be configured to download dependencies that can be declared in a `pom.xml` file or in the Ant build file directly.

This configuration can be contained in your Ant `build.xml` or a separate file that is imported. A minimal example for resolving dependencies from a repository manager running on localhost is shown below:

**Minimal Aether Configuration in an Ant file**

```
<project xmlns:aether="antlib:org.eclipse.aether.ant" ....>
  <taskdef uri="antlib:org.eclipse.aether.ant" resource="org/eclipse/aether/ant/antlib.xml">
    <classpath>
      <fileset dir="${aether.basedir}" includes="aether-ant-tasks-*.jar" />
    </classpath>
  </taskdef>
  <aether:mirror id="mirror" url="http://localhost:8081/repository/maven-public/" mirrorOf="*"/>
...
</project>
```

These minimal settings allow the `aether:resolve` task to download the declared dependencies.

To deploy build outputs to a repository with the `aether:deploy` task, user authentication and details about the target repositories have to be added.

Full example projects can be found in the `ant-aether` folder of the [example project](https://github.com/sonatype/nexus-book-examples/tree/nexus-3.x) in the `nexus-3.x` branch. A full build of the `simple-project`, including downloading the declared dependencies and uploading the build output to the repository manager can be invoked with:

```
cd ant-aether/simple-project
ant deploy
```

## Configuring Gradle

[Gradle](https://www.gradle.org/) has a built-in dependency management component that supports the Maven repository format.

In order to configure a Gradle project to resolve dependencies declared in the `build.gradle` file, a Maven repository as shown in _Gradle Repositories Configuration_ has to be declared.

**Gradle Repositories Configuration**

```
repositories {
    maven {
        url "https://nexus.example/repository/repository-name/"
    }
}
```

These minimal settings allow Gradle to download the declared dependencies. You can also see [Gradle's documentation on dependencies](https://docs.gradle.org/current/userguide/declaring_repositories.html#sec:declaring_custom_repository) for more information.

For guidance on publishing to Maven, see [Gradle's documentation](https://docs.gradle.org/current/userguide/publishing_maven.html).

### Proxying and Authenticating in Gradle

Configure authentication using a block similar to the following example:

```
repositories {
        maven {
                credentials {
                        username "$user"
                        password "$password"
                }
                url "https://nexus.example/repository/repository-name/"
        }
}
```

## SBT

[sbt](http://www.scala-sbt.org/) has a built in dependency management component and defaults to the Maven repository format. In order to configure a sbt project to resolve dependencies declared in `build.sbt` file, a resolver, as shown in _SBT Resolvers Configuration_ has to be declared.

**SBT Resolvers Configuration**

```
resolvers += "Nexus" at "http://localhost:8081/repository/maven-public/"
```

These minimal settings allow sbt to download the declared dependencies.

To deploy build outputs to a repository with the publish task, user credentials can be declared in the `build.sbt` file:

```
credentials += Credentials("Sonatype Nexus",
"nexus.scala-tools.org", "admin", "admin123")
```

The `publishTo` configuration:

```
publishTo <<= version { v: String =>
  val nexus = "http://localhost:8081/"
  if (v.trim.endsWith("SNAPSHOT"))
    Some("snapshots" at nexus + "repository/maven-snapshots")
  else
    Some("releases" at nexus + "repository/maven-releases")
```

Further documentation can be found in the [sbt documentation on publishing](http://www.scala-sbt.org/release/docs/Publishing.html).

## Leiningen

[Leiningen](http://leiningen.org/) has a built in dependency management component and defaults to the Maven repository format. As a build tool it is mostly used for projects using the Clojure language. Many libraries useful for these projects are published to the Clojars repository. If you want to use these, you have to create two proxy repositories with the remote URL `http://clojars.org/repo/`.

This repository is mixed and you therefore must create a release and a snapshot proxy repository and then add both to the public group.

In order to configure a Leiningen project to resolve dependencies declared in the `project.clj` file, a `mirrors` section overriding the built in `central` and clojars repositories as shown in _Leiningen Configuration_ has to be declared.

**Leiningen Configuration**

These minimal settings allow Leiningen to download the declared dependencies.

```
:mirrors {
    "central" {:name "Nexus"
                          :url "http://localhost:8081/repository/maven-public/"
                          :repo-manager true}
  #"clojars" {:name "Nexus"
                          :url ""http://localhost:8081/repository/maven-public/""
                          :repo-manager true}
                        }
```

To deploy build outputs to a repository with the deploy command, the target repositories have to be add to `project.clj` as `deploy-repositories`. This avoids Leiningen checking for dependencies in these repositories, which is not necessary, since they are already part of the `public` repository group used in `mirrors`.

```
:deploy-repositories [\
    ["snapshots" "http://localhost:8081/repository/maven-snapshots"]\
    ["releases" "http://localhost:8081/repository/maven-releases"]\
  ]
```

User credentials can be declared in `~/.lein/credentials.clj.gpg` or will be prompted for.

Further documentation can be found on the [Leiningen website](http://leiningen.org/).

## Maven Repository Format

Maven developers are familiar with the concept of a repository since repositories are used by default. The primary type of binary component in a Maven format repository is a JAR file containing Java byte code. This is due to the Java background of Maven and the fact that the default component type is a JAR. Practically, however, there is no limit to what type of component can be stored in a Maven repository. For example, you can easily deploy WAR or EAR files, source archives, Flash libraries and applications, Android archives or applications, or Ruby libraries to a Maven repository.

Every software component is described by an XML document called a Project Object Model (POM). This POM contains information that describes a project and lists a project’s dependencies — the binary software components, which a given component depends upon for successful compilation or execution.

When Maven downloads a component like a dependency or a plugin from a repository, it also downloads that component’s POM. Given a component’s POM, Maven can then download any other components that are required by that component.

Maven and other tools, such as Ivy or Gradle, interact with a Maven repository to search for binary software components, model the projects they manage, and retrieve software components on-demand from a repository.

### The Central Repository

When you download and install Maven without any customization, it retrieves components from the Central Repository. It serves millions of Maven users every single day. It is the default, built-in repository using the Maven repository format and is managed by Sonatype. Statistics about the size of the Central Repository are available at [https://search.maven.org/stats](https://search.maven.org/stats).

The Central Repository is the largest repository for Java-based components. It can be easily used from other build tools as well. You can look at the Central Repository as an example of how Maven repositories operate and how they are assembled. Here are some of the properties of release repositories such as the Central Repository:

#### Component Metadata

All software components added to the Central Repository require proper metadata, including a Project Object Model (POM) for each component that describes the component itself and any dependencies that the software component might have.

#### Release Stability

Once published to the Central Repository, a component and the metadata describing that component never change. This property of a release repository, like the Central Repository, guarantees that projects that depend on releases will be repeatable and stable over time. While new software components are being published every day, once a component is assigned a release number on the Central Repository, there is a strict policy against modifying the contents of a software component after a release.

#### Component Security

The Central Repository contains cryptographic hashes and PGP signatures that can be used to verify the authenticity and integrity of software components served and supports connections securely via HTTPS.

#### Performance

The Central Repository is exposed to the users globally via a high-performance content delivery network of servers.

In addition to the Central Repository, there are several major organizations, such as Red Hat, Oracle or the Apache Software Foundation, which maintain separate additional repositories. The best practice to facilitate these available repositories is to install Nexus Repository to use as a proxy and cache the contents on your own network.

### Component Coordinates and the Repository Format

Component coordinates create a unique identifier for a component. Maven coordinates use the following values: groupId, artifactId, version, and packaging. This set of coordinates is often referred to as a GAV coordinate, which is short for Group, Artifact, or Version coordinate. The GAV coordinate standard is the foundation for Maven’s ability to manage dependencies. Four elements of this coordinate system are described below:

#### GroupId

A group identifier groups a set of components into a logical group. Groups are often designed to reflect the organization under which a particular software component is being produced. For example, software components being produced by the Maven project at the Apache Software Foundation are available under the groupId `org.apache.maven`.

#### ArtifactId

An artifactId is an identifier for a software component and should be a descriptive name. The combination of groupId and artifactId must be unique for a specific project.

#### Version

The version of a project ideally follows the established convention of [semantic versioning](http://semver.org/). For example, if your simple-library component has a major release version of `1`, a minor release version of `2`, and a point release version of `3`, your version would be `1.2.3`. Versions can also have alphanumeric qualifiers which are often used to denote release status. An example of such a qualifier would be a version like "1.2.3-BETA" where BETA signals a stage of testing meaningful to consumers of a software component.

#### Packaging

Maven was initially created to handle JAR files, but a Maven repository is completely agnostic about the type of component it is managing. Packaging can be anything that describes any binary software format including the following:

```
zip, nar, war, ear, sar, aar
```

Tools designed to interact with Maven repositories translate component coordinates into a URL that corresponds to a location in a Maven repository. If a tool such as Maven is looking for version `1.2.0` of the `commons-lang` JAR in the group `org.apache.commons`, this request is translated into:

```
<repoURL>/org/apache/commons/commons-lang/1.2.0/commons-lang-1.2.0.jar
```

Maven also downloads the corresponding POM for `commons-lang 1.2.0` from:

```
<repoURL>/org/apache/commons/commons-lang/1.2.0/commons-lang-1.2.0.pom
```

This POM may contain references to other components, which are then retrieved from the same repository using the same URL patterns.

### Release and Snapshot Repositories

A Maven repository stores two types of components: releases and snapshots. Release repositories are for stable, static release components. Snapshot repositories are frequently updated repositories that store binary software components from projects under constant development.

While it is possible to create a repository that serves both release and snapshot components, repositories are usually segmented into release or snapshot repositories serving different consumers and maintaining different standards and procedures for deploying components. Much like the difference between networks, a release repository is considered like a production network and a snapshot repository is more like a development or a testing network. While there is a higher level of procedure and ceremony associated with deploying to a release repository, snapshot components can be deployed and changed frequently without regard for stability and repeatability concerns.

The two types of components managed by a repository manager are:

#### Release

A release component is a component that was created by a specific, versioned release. For example, consider the `1.2.0` release of the `commons-lang` library stored in the Central Repository. This release component, `commons-lang-1.2.0.jar`, and the associated POM, `commons-lang-1.2.0.pom`, are static objects that never change in the Central Repository. Released components are considered to be solid, stable, and perpetual to guarantee that builds that depend upon them are repeatable over time. The released JAR component is associated with a PGP signature, an MD5, and a SHA check-sum which can be used to verify both the authenticity and integrity of the binary software component.

#### Snapshot

Snapshot components are components generated during the development of a software project. A Snapshot component has both a version number such as `1.3.0` or `1.3` and a time-stamp in its name. For example, a snapshot component for `commons-lang 1.3.0` might have the name `commons-lang-1.3.0.-20090314.182342-1.jar` the associated POM, MD5, and SHA hashes would also have a similar name. To facilitate collaboration during the development of software components, Maven and other clients who know how to consume snapshot components from a repository also know how to interrogate the metadata associated with a Snapshot component to retrieve the latest version of a Snapshot dependency from a repository.

A project under active development produces snapshot components that change over time. A release is comprised of components that remain unchanged over time.

Looking at the Maven repository format and associated concepts and ideas allowed you to grasp some of the details and intricacies involved with different tools and repository formats, that will help you appreciate the need for repository management.
