Layer 8Ehrlicher Tech-Support

Maven: ein Leerzeichen in mirrorOf legt den Spiegel still

!repo1,* spiegelt alles außer repo1. !repo1, * spiegelt gar nichts. Der Unterschied ist ein Leerzeichen, und Maven sagt dazu kein einziges Wort.

Aufwand:
ca. 20 Min.

Das Symptom

Der Firmenspiegel ist eingerichtet, die settings.xml sieht richtig aus, und trotzdem zieht Maven weiter direkt aus dem öffentlichen Repository – oder scheitert im abgeschotteten Netz an genau diesem Versuch. Im Log taucht die Adresse des Spiegels nirgends auf.

Maven meldet dazu keine ungültige Konfiguration, keine Warnung, keinen Hinweis. Der Build verhält sich einfach so, als stünde in der Datei überhaupt kein Spiegel.

Die „Layer 8“-Wahrheit

Der Klassiker sitzt in mirrorOf und ist ein Leerzeichen. Die Apache-Dokumentation warnt in einem eigenen Absatz davor und liefert das Beispiel mit: Ein Spiegel mit !repo1, * spiegelt nichts, während !repo1,* alles außer repo1 spiegelt. Ein Zeichen Unterschied, zwei entgegengesetzte Wirkungen. Wer die Datei mit einem Formatierer bearbeitet oder den Wert aus einer Wiki-Seite kopiert hat, in der jemand die Liste „für die Lesbarkeit“ aufgelockert hat, hat den Spiegel damit lautlos abgeschaltet.

Lautlos ist hier das Stichwort. mirrorOf ist ein Musterausdruck, kein geprüfter Schlüssel. Passt er auf keine Repository-ID, ist das für Maven kein Fehler, sondern ein leeres Ergebnis – es gibt eben keinen Spiegel, also lädt es direkt. Im offenen Netz merkt das niemand, es wird nur langsamer und der Repository-Manager bleibt leer. Im abgeschotteten Firmennetz äußert sich derselbe Tippfehler als Verbindungsfehler zu repo.maven.apache.org, und dann sucht ein halbes Team im Proxy nach einem Problem, das in einer Leertaste sitzt.

Die zweite stille Falle steht direkt daneben: Es kann höchstens einen Spiegel je Repository geben. Wer zwei Einträge mit demselben mirrorOf hinschreibt, in der Annahme, Maven würde bei Ausfall des einen auf den anderen ausweichen, irrt – Maven aggregiert nicht, es nimmt den ersten Treffer. Der zweite Eintrag ist reine Dekoration, die sich beim Lesen wie eine Absicherung anfühlt.

Die echte, verifizierte Lösung

1000 % faktenbasiert. Jeder Befehl ist real, jeder Pfad existiert. Schritt für Schritt:

  1. 1.

    Den mirrorOf-Wert zeichenweise ansehen

    Kein Überfliegen – das Zeichen, um das es geht, ist unsichtbar. Die Dokumentation warnt ausdrücklich vor zusätzlichem Leerraum um Bezeichner und Platzhalter in kommagetrennten Listen und nennt das Beispiel gleich mit: !repo1, * spiegelt nichts, !repo1,* spiegelt alles außer repo1.

    grep -n mirrorOf ~/.m2/settings.xml | cat -A
    
  2. 2.

    Das Leerzeichen entfernen

    Die Korrektur ist eine Tastenbewegung, das Auffinden war die Arbeit. Ein sauber geschriebenes Muster ohne Leerraum, mit der Ausnahme direkt hinter dem Komma.

    <mirror>
      <id>internal-repository</id>
      <name>Maven Repository Manager running on repo.mycompany.com</name>
      <url>http://repo.mycompany.com/proxy</url>
      <mirrorOf>external:*,!foo</mirrorOf>
    </mirror>
    
  3. 3.

    Doppelte Spiegel für dieselbe Quelle auflösen

    Stehen mehrere Spiegel mit demselben mirrorOf-Wert in der Datei, ist das keine Ausfallsicherung. Es kann höchstens einen Spiegel je Repository geben; Maven nimmt den ersten Treffer und ignoriert den Rest. Wer Ausfallsicherheit will, baut sie im Repository-Manager, nicht in der settings.xml.

  4. 4.

    Statt * lieber external:* verwenden

    Ein mirrorOf von * leitet wirklich jede Repository-ID um, auch localhost-Adressen und dateibasierte Repositories. external:* nimmt genau diese beiden Gruppen aus. Das ist der Grund, warum plötzlich Integrationstests scheitern, nachdem jemand den Firmenspiegel auf * gestellt hat.

    <mirrorOf>external:*</mirrorOf>
    
  5. 5.

    Ausnahmen bewusst setzen, statt sie zu vergessen

    Ein Ausrufezeichen vor einer Repository-ID nimmt diese vom Spiegel aus und lässt sich mit den Platzhaltern kombinieren. Praktisch für das eine interne Repository, das gerade nicht über den Spiegel laufen soll. Wichtig bleibt: kein Leerzeichen hinter dem Komma, sonst greift wieder gar nichts.

    <mirrorOf>*,!repo1</mirrorOf>
    

Häufige Fragen (FAQ)

?Warum meldet Maven keinen Fehler, wenn mirrorOf unsinnig ist?

Weil mirrorOf ein Musterausdruck ist und kein Schlüssel, der geprüft würde. Passt das Muster auf keine einzige Repository-ID, ist das kein Fehlerfall, sondern ein leeres Ergebnis: Maven spiegelt dann eben nichts und lädt direkt aus den Original-Repositories. Erst wenn diese im Firmennetz gesperrt sind, äußert sich das als Fehler – und dann als Netzwerkproblem, nicht als Konfigurationsproblem.

?Ich habe zwei Spiegel mit demselben mirrorOf eingetragen. Wird das als Ausfallsicherung genutzt?

Nein. Die Dokumentation ist an dieser Stelle eindeutig: Es kann höchstens einen Spiegel je Repository geben. Maven fasst mehrere Einträge nicht zusammen, sondern nimmt schlicht den ersten Treffer. Der zweite Eintrag ist tote Konfiguration, die man beim Lesen für eine Absicherung hält.

?Was ist der Unterschied zwischen * und external:*?

* passt auf alle Repository-IDs, ausnahmslos. external:* passt auf alle außer denen auf localhost und den dateibasierten. Letzteres ist für Integrationstests gedacht, deren lokale Testrepositories man gerade nicht über den Firmenspiegel umleiten will.

Belege

Diese Seite ist gegen die folgenden Primärquellen geprüft – Hersteller, Standard oder Gesetzestext. Wer es nicht glaubt, muss es nicht: Da steht, wo es nachzulesen ist.

Zuletzt geprüft am . Dokumentation altert – ein Datum daneben ist der einzige ehrliche Umgang damit.

Auch zu finden unter

Verwandte Fehler

SWLästigCould not resolve dependencies

Maven: Could not resolve dependencies

Maven findet eine Abhängigkeit nicht? Meist fehlt das Repository, ein Proxy blockt, oder ein halb geladenes Paket verstopft den Cache.