Skip to content
This repository has been archived by the owner on Nov 19, 2020. It is now read-only.

Latest commit

 

History

History
499 lines (386 loc) · 21 KB

chapter-maven.asciidoc

File metadata and controls

499 lines (386 loc) · 21 KB

Maven Repositories with Apache Maven and Other Tools

{inall}

Introduction

Historically {nxrm} started as a repository manager supporting 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 chapter explains the default configuration included in {pro} and {oss}, instructions for creating further Maven repositories as well as searching and browsing the repositories. Build tool configuration for Apache Maven, Apache Ant, Gradle and others tools follow. The configuration examples take advantage of the repository manager merging many repositories and exposing them via a repository group.

Maven Repository Format

Apache Maven 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 [concepts-maven-format].

The format is used by many publicly available repositories. The Central Repository 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 [admin-repositories], specifics of the Maven repository format can be configured for each repository in the 'Maven 2' section.

Version policy
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 ublished them to public repositories, such as the Central Repository. These tools rely on these changed conventions.

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 accessig 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.

Strict Content Type Validation

Maven repositories can be configured to validate any new components to see if the MIME-type corresponds to the content of the file by enabling this setting. Any files with a mismatch are rejected.

Proxying Maven Repositories

A default installation of {nxrm} 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 [admin-repositories].

Minimal configuration steps are:

This creates a repository using the a '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://maven.oracle.com) 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 https://maven.oracle.com, with these additional steps:

  1. Add https://maven.oracle.com to the 'Remote storage' field.

  2. Check 'Authentication', in the 'HTTP' section. 'Username' should be automatically selected under 'Authentication type'.

  3. Enter the 'Username' and 'Password' from your Oracle account.

  4. Check 'HTTP request settings'.

  5. Check 'Enable circular redirects'.

  6. Check 'Enable cookies'.

After applying these settings to your 'maven2 (proxy)' 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 {nxrm} includes a 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 [admin-repositories].

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 [admin-repositories].

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 [browse-browse].

Components can be serched in the user interface as described in [search-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'. Simple 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, 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 as shown in Listing: Configuring Maven to Use a Single Repository Group.

Listing: 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 Listing: 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.

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 looked from a 'server' section in a users settings.xml using the nexus value used in the id fields:

<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 documentation examples project 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 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 in Listing: Minimal Ivy Configuration in an Ant file.

Listing: 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 documentation examples project 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 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 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 in Listing: Minimal Aether Configuration in an Ant file.

Listing: 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 documentation examples project 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 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 build.gradle file, a maven repository as shown in Listing: Gradle Repositories Configuration has to be declared.

Listing: Gradle Repositories Configuration
repositories {
    maven {
        url "http://localhost:8081/repository/maven-public/"
    }
}

These minimal settings allow Gradle to download the declared dependencies.

To deploy build outputs to a repository with the uploadArchives task, user authentication can be declared in e.g., gradle.properties:

nexusUrl=http://localhost:8081
nexusUsername=admin
nexusPassword=admin123

and then used in the uploadArchives task with a mavenDeployer configuration from the Maven plugin:

uploadArchives {
    repositories {
        mavenDeployer {
            repository(url: "${nexusUrl}/repository/maven-releases/") {
                authentication(userName: nexusUsername, password: nexusPassword)
            }
            snapshotRepository(url: "${nexusUrl}/repository/maven-snapshots") {
                authentication(userName: nexusUsername, password: nexusPassword)
            }
        }
    }
}

Full example projects can be found in the gradle folder of the documentation book examples project 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 gradle/simple-project
gradle upload

SBT

sbt 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 Listing: SBT Resolvers Configuration has to be declared.

Listing: 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.

Leiningen

Leiningen 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 have to 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 Listing: Leiningen Configuration has to be declared.

Listing: Leiningen Configuration
  :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}
                        }

These minimal settings allow Leiningen to download the declared dependencies.

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.