Das Symptom
Ein Team findet einen Fehler in seiner Bibliothek 1.0, behebt ihn und lädt das Artefakt unter derselben Version 1.0 erneut ins Firmen-Repository hoch, weil die Version ja noch keiner benutzt hat. Danach bauen die Kollegen weiter mit der fehlerhaften Fassung, der CI-Server auch, und nur der eine Rechner, der die alte nie geladen hatte, hat den Fix. Wochen später gibt es zwei verschiedene Dateien mit derselben Koordinate im Umlauf, und niemand kann sagen, welche wo läuft. Dieselbe Fehlannahme in Gegenrichtung: Für eine SNAPSHOT-Abhängigkeit wird ein Cache-Problem vermutet, weil sie sich beim nächsten Build plötzlich ändert.
Die „Layer 8“-Wahrheit
Die Maven-Dokumentation zu Repositories beschreibt, wann überhaupt heruntergeladen wird: „Downloading in Maven is triggered by a project declaring a dependency that is not present in the local repository (or for a SNAPSHOT, when the remote repository contains one that is newer).“ Eine Release-Version, die einmal unter ~/.m2/repository liegt, wird also nie wieder angefragt. Das ist kein Versäumnis, sondern der Vertrag, den der Getting-Started-Guide ausspricht: „The SNAPSHOT value refers to the ‘latest’ code along a development branch, and provides no guarantee the code is stable or unchanging. Conversely, the code in a ‘release’ version (any version value without the suffix SNAPSHOT) is unchanging.“
Wer ein Release überschreibt, verletzt diesen Vertrag, und Maven kann das gar nicht bemerken, weil es auf der Abrufseite nie nachsieht. Auch der Schalter, der angeblich alles frisch holt, tut es nicht: Die CLI-Referenz beschreibt -U, –update-snapshots als „Forces a check for missing releases and updated snapshots on remote repositories“. Fehlende Releases und aktualisierte Snapshots; ein vorhandenes Release fehlt nicht und wird nicht neu geladen.
Richtig ist: Der Fix wird als 1.0.1 veröffentlicht; wer laufend ändern will, arbeitet mit 1.1-SNAPSHOT, denn nur dafür prüft Maven auf neuere Fassungen. Repository-Manager erlauben es deshalb in der Grundeinstellung nicht, ein Release zu überschreiben, und diese Sperre ist der einzige Ort, an dem der Vertrag technisch durchgesetzt wird. Wo er schon verletzt wurde, hilft nur das Löschen des Artefaktverzeichnisses im lokalen Repository auf jedem Rechner und jedem CI-Server, gefolgt von einer neuen Versionsnummer, damit es das letzte Mal war.
Die Gegenrichtung des Irrtums ist derselbe Vertrag von der anderen Seite: Eine SNAPSHOT-Abhängigkeit, die sich zwischen zwei Builds ändert, verhält sich genau so, wie der Guide es beschreibt. Wer dort Stabilität erwartet, hat die falsche Versionsart gewählt, nicht einen Fehler gefunden.