Sebastian Hempel bio photo

Sebastian Hempel

Software Crafter, Clean-Code-Developer, JEE Professional, Puppet-Master, OpenSource Fanboy, Alfisti

Email Twitter Google+ XING Instagram Github

Die Konfiguration von Repositories in Maven ist eine Sache. Die Verwaltung von Repositories im Repository-Manager Nexus die andere. Verwirrend kann es werden, wenn man beide Konfigurationen nicht aufeinander abstimmt. In diesem Beitrag stelle ich die derzeit für mich funktionierende und abgstimmte Konfiguration der Repositories in Maven und in Nexus vor.

Repositories des Super POM

Die “Mutter aller POMs” wird zusammen mit Maven ausgeliefert. Jede Maven Version bringt ihre eigene Super POM Datei mit. In der Super POM werden globale, für alle weitern POMs gültige Vorgaben festgelegt. Jedes POM eines Projekts erbt direkt oder indirekt die Einstellungen aus der Super POM.

In der Super POM wird das Repository mit der Id central definiert. Aus diesem Repository versucht Maven alle definierten Abhängigkeiten aufzulösen.

<repository>
  <id>central</id>
  <name>Central Repository</name>
  <snapshots>
    <enabled>false</enabled>
  </snapshots>
  <url>http://repo.maven.apache.org/maven2</url>
</repository>

Das “Central Repository” wird vom Unternehmen Sonatype betrieben und wird auch als “Maven Central” bezeichnet. Aus diesem Repository können nur unter einer OpenSource Lizenz stehende Artefakte heruntergeladen werden.

eigenes (lokales) Repository

Sollen eigene oder Artefakte von Dritt-Herstellern unter einer nicht OpenSource Lizenz heruntergeladen werde, ist in Maven ein weiteres Repository zu definieren. Das Repository wird selbst im lokalen Netzwerk betrieben. Zur Realisierung eines derartigen Repositories kommen Repository-Manager wie Nexus oder Artifactory zum Einsatz.

Um Maven weitere Repositories bekannt zu machen stehen zwei Möglichkeiten zur Verfügung:

  1. Definition des Repositories in der POM des Projekts

  2. Definition des Repositories in der settings.xml in einem Profil

Repository in der POM definieren

Soll das (neue) Repository in der Beschreibung des Projekts selbst definiert werden, verwendet man das <repositories> Element der POM.

<repositories>
  <repository>
    <id>releases</id>
    <name>Releases</name>
    <releases>
      <enabled>true</enabled>
      <updatePolicy>always</updatePolicy>
      <checksumPolicy>warn</checksumPolicy>
    </releases>
    <snapshots>
      <enabled>false</enabled>
    </snapshots>
    <url>https://development.local.domain/nexus/content/repositories/releases</url>
  </repository>
</repositories>

Neben dem central Repository steht Maven nun das releases Repository zur Verfügung. Kann eine Abhängigkeit nicht über das Central Repository aufgelöst werden, wird nun zusätzlich im Releases Repository nach der Abhängigkeit gesucht. Mit dieser Art der Konfiguration ist es möglich, ein Repository mit Snapshot-Versionen zu definieren.

<repositories>
  <repository>
    <id>snapshots</id>
    <name>Snapshots</name>
    <releases>
      <enabled>false</enabled>
    </releases>
    <snapshots>
      <enabled>true</enabled>
      <updatePolicy>always</updatePolicy>
      <checksumPolicy>warn</checksumPolicy>
    </snapshots>
    <url>https://development.local.domain/nexus/content/repositories/snapshots</url>
  </repository>
</repositories>

Definition in der settings.xml

Diese beiden Definitionen müssen in jedem (Parent-) POM wiederholt werden. Werden die Repositories in mehreren Projekten benötigt, kann die Definition auch über die settings.xml für alle Projekte eines Benutzers definiert werden.

In der Konfigurationsdatei muss hierfür ein Profil (default) definiert werden. In diesem Profil werden die beiden Repositories (Snapshots und Releases) defininiert. Zum Abschluss wird dieses Profil aktiviert.

<profiles>
  <profile>
    <id>default</id>
    <repositories>
      <repository>
        <id>releases</id>
        <name>Releases</name>
        <releases>
          <enabled>true</enabled>
          <updatePolicy>always</updatePolicy>
          <checksumPolicy>warn</checksumPolicy>
        </releases>
        <snapshots>
          <enabled>false</enabled>
        </snapshots>
        <url>https://development.local.domain/nexus/content/repositories/releases</url>
      </repository>
      <repository>
        <id>snapshots</id>
        <name>Snapshots</name>
        <releases>
          <enabled>false</enabled>
        </releases>
        <snapshots>
          <enabled>true</enabled>
          <updatePolicy>always</updatePolicy>
          <checksumPolicy>warn</checksumPolicy>
        </snapshots>
        <url>https://development.local.domain/nexus/content/repositories/snapshots</url>
      </repository>
    </repositories>
  </profile>
</profiles>

<activeProfiles>
  <activeProfile>default</activeProfile>
</activeProfiles>

Veröffentlichung von Artefakten in einem Repository

Damit Maven in der Lifecycle Phase deploy das erstellte Artefakt in einem Repository veröffentlichen kann, muss dieses in der POM definiert werden.

Die Repositories werden hierzu im Zweig <distributionManagement> zusätzlich zum “lesenden” Zugriff über den Zweig <repositories> definiert.

<distributionManagement>
  <repository>
    <id>releases</id>
    <name>Releases</name>
    <url>https://development.local.domain/nexus/content/repositories/releases/</url>
  </repository>
  <snapshotRepository>
    <id>snapshots</id>
    <name>Snapshots</name>
    <url>https://development.local.domain/nexus/content/repositories/snapshots/</url>
  </snapshotRepository>
</distributionManagement>

Evtl. notwendige Zugangskennungen für den Upload der Artefakte werden unter der gleichen Id in der settings.xml angegeben.

Mirror von Maven Central

Ein Repository-Manager wie z.B. Nexus wird nicht nur zur Verwaltung eines lokalen Repositories verwendet. Von Nexus selbst verwaltete Repositories sind vom Typ hosted. Wird vom Repository-Manager nur ein Spiegel (Mirror) verwaltet, sind diese Repositories vom Typ proxy.

central mirror

Soll Maven auf einen so definierten Spiegel von central und nicht direkt auf die URL aus dem Super POM zugreifen, ist dies in der settings.xml zu definieren.

<mirrors>
  <mirror>
    <id>central</id>
    <name>Central</name>
    <url>https://development.local.domain/nexus/content/repositories/central/</url>
    <mirrorOf>central</mirrorOf>
  </mirror>
</mirrors>

Durch die Angabe von <mirrorOf>central</mirrorOf> werden alle Anfragen, die normalerweise an das Maven Central Repository gerichtet sind, an diesen (lokalen) Spiegel umgeleitet.

Zusammenfassung von mehreren Proxies

In Nexus steht das Konzept der Repository Group zur Verfügung. Eine Group ist kein eigenes Repository, in dem Artefakte abgelegt oder gespiegelt werden. In einer Group werden mehrere Repositories zusammengefasst. Danach kann auf alle Repositories über die definierte Gruppe zugegriffen werden. Derartige Repository sind vom Typ group.

Über eine Gruppe (z.B. Public Repositories) können z.B. die Mirror von Maven Central, Java Net und Public JBoss zusammen gefasst werden.

public repositories

Auf Seiten von Maven wird der Mirror von central auf diese Gruppe gesetzt. Somit kann Maven nicht nur Artefakte aus Maven Central sondern auch von allen anderen Repositories der Repository Group auflösen.

<mirrors>
  <mirror>
    <id>public</id>
    <name>Public Repositories</name>
    <url>https://development.local.domain/nexus/content/groups/public/</url>
    <mirrorOf>central</mirrorOf>
  </mirror>
</mirrors>

Es ist nicht zu empfehlen in eine Repository Group sowohl interne (hosted) als auch externe (proxy) Repositories zusammen zu fassen. Von externen Repositories wird nur gelesen. Auch werden von diesen normalerweise keine SNAPSHOT-Versionen aufgelöst.

Von internen Repositories werden oft auch SNAPSHOT-Versionen benötigt, um auf die aktuellen Versionsstände eines anderen Projekts zuzugreifen. Fasst man alle diese Repositories zu einer Repository Group zusammen, gibt es oft Probleme beim Auflösen der Abhängigkeiten zu internen Artefakten.

Zusammenfassung

Zusammenfassend sind bei mir die Repositories wie folgt konfiguriert:

  • Proxy-Repositories für die externen Repositories Maven Central, Java Net und Public JBoss

  • Hosted Repositories für Snapshots und Releases

  • Repository Group für alle öffentlichen Repositories

  • Konfiguration der Repository Group als mirror of central in der settings.xml

  • Konfiguration der Snapshots und Releases Repositories in der settings.xml (repositories) und der pom.xml (distributionManagement)