Wie bereinige ich alte Abhängigkeiten von Maven-Repositorys?

69

Ich habe zu viele Dateien im Ordner .m2, in denen Maven heruntergeladene Abhängigkeiten speichert. Gibt es eine Möglichkeit, alle alten Abhängigkeiten zu bereinigen? Wenn beispielsweise eine Abhängigkeit mit 3 verschiedenen Versionen besteht: 1, 2 und 3, darf nach der Reinigung nur die dritte vorhanden sein. Wie kann ich das für alle Abhängigkeiten im Ordner .m2 tun?

Kirsche
quelle
3
Löschen Sie einfach den .m2repositoryOrdner. Es wird automatisch erstellt, sobald Sie das Projekt kompilieren.
user2339071
3
oder größere Festplatte kaufen und egal :)
Smajlo
8
Vielleicht gibt es eine elegantere Lösung, als auf die Kompilierung zu warten und Geld für die Festplatte auszugeben? :) Aber im Ernst , ich arbeite remote an einer virtuellen Maschine, daher sind Speicherplatz (klein) und Kompilierungszeit (lang) von Bedeutung. Deshalb kann ich Festplatte oder Prozessor nicht einfach wechseln. Ich brauche also einen Weg, um es effektiver zu nutzen.
Cherry
Wenn Sie die IDE sowie ALLE Ihre letzten Projekte geöffnet haben, verhindern die Dateisystem-Sperren, dass Sie die verwendeten Gläser löschen können
digitale Illusion
Wie kann die Bereinigung von Abhängigkeiten durch eine POM-Datei erreicht werden?
Tushar Banne

Antworten:

37

Wenn Sie unter Unix arbeiten, können Sie die Zugriffszeit der dort enthaltenen Dateien verwenden. Aktivieren Sie einfach die Zugriffszeit für Ihr Dateisystem, führen Sie einen sauberen Build aller Ihrer Projekte aus, für die Sie Abhängigkeiten beibehalten möchten, und führen Sie dann Folgendes aus (UNTESTED!):

find ~/.m2 -amin +5 -iname '*.pom' | while read pom; do parent=`dirname "$pom"`; rm -Rf "$parent"; done

Dadurch werden alle * .pom-Dateien gefunden, auf die zuletzt vor mehr als 5 Minuten zugegriffen wurde (vorausgesetzt, Sie haben Ihre Builds vor maximal 5 Minuten gestartet), und ihre Verzeichnisse gelöscht.

Fügen Sie "echo" vor dem rm hinzu, um einen "Trockenlauf" durchzuführen.

Florian
quelle
17
Unter OSX (könnte auch mit GNU-Tools funktionieren), find ~/.m2/repository/ -atime +30 -iname '*.pom' -print0 | while read -d '' -r pom; do echo rm -rf "$(dirname $pom)"; donewo atimein Tagen (im Vergleich zu aminin Minuten)
Brice
2
Ich benutze find ~/.m2 -atime +1w -iname '*.pom' | while read pom; do parent=$(dirname "$pom"); rm -rf "$parent"; donewas für mich unter OSX funktioniert. Sollte auch auf anderen Unixen gut
funktionieren
Ich habe mich gerade in "find" verliebt
Jonas Eicher
29

Kurze Antwort - Gelöschter .m2-Ordner in {user.home}. ZB in Windows 10 ist Benutzer zu Hause C:\Users\user1. Erstellen Sie Ihr Projekt mit neu mvn clean package. Es bleiben nur die Abhängigkeiten übrig, die von den Projekten benötigt werden.

Lange Antwort - Der Ordner .m2 ist wie ein normaler Ordner und der Inhalt des Ordners wird aus verschiedenen Projekten erstellt. Ich denke, es gibt keine Möglichkeit, automatisch herauszufinden, welche Bibliothek "alt" ist. In der Tat ist alt ein vages Wort. Es kann so viele Gründe geben, warum eine frühere Version einer Bibliothek in einem Projekt verwendet wird. Daher ist es nicht möglich zu bestimmen, welche nicht verwendet wird.

Alles, was Sie tun können, ist, den Ordner .m2 zu löschen und alle Ihre Projekte neu zu erstellen. Anschließend wird der Ordner automatisch mit der gesamten erforderlichen Bibliothek erstellt.

Wenn Sie Bedenken haben, dass nur eine bestimmte Version einer Bibliothek in allen Projekten verwendet werden soll; Es ist wichtig, dass der POM des Projekts auch auf die neueste Version aktualisiert wird. Wenn unterschiedliche POMs auf unterschiedliche Versionen der Bibliothek verweisen, werden alle in .m2 heruntergeladen.

Gyanendra Dwivedi
quelle
"Daher ist es nicht möglich zu bestimmen, welches nicht verwendet wird." Ich brauche diese Bestimmung nicht, ich muss nur neue Versionen hinterlassen.
Cherry
2
Löschen Sie dann den Ordner .m2 und stellen Sie sicher, dass alle Projekte nur neue Versionen des JAR-Eintrags in pom.xml enthalten. Erstellen Sie das Projekt neu. Der Ordner .m2 bleibt nur mit der neuesten Version erhalten.
Gyanendra Dwivedi
1
delete .m2Dies führt dazu, dass alle Abhängigkeiten gelöscht und neue aus dem extrem langsamen Repository heruntergeladen werden.
Cherry
Für das angegebene Problem - eine für alle geeignete Lösung - könnten wir den oben genannten Weg gehen. Für das Problem der Langsamkeit würde ich empfehlen, dass das Projekt ein lokales Repo konsultiert (eine Art Produkt-Repository-Setup in der Organisation); falls nicht verfügbar Download aus dem öffentlichen Repository. Zu einem bestimmten Zeitpunkt wird empfohlen, das Artefakt schließlich in das lokale Repository hochzuladen - sofern es in allen Projekten so häufig verwendet wird.
Gyanendra Dwivedi
18

Wenn Sie eine POM-Datei für ein Maven-Projekt haben, können Sie alle Abhängigkeiten im lokalen Repository (standardmäßig ~ / .m2 / respository) mithilfe des Apache Maven-Abhängigkeits- Plugins entfernen .

Es enthält die dependency:purge-local-repositoryFunktionalität, mit der die Projektabhängigkeiten aus dem lokalen Repository entfernt und optional neu aufgelöst werden.

Um die lokalen Abhängigkeiten zu bereinigen, müssen Sie nur den optionalen Parameter reResolve verwenden und ihn auf false setzen, da er standardmäßig auf true gesetzt ist.

Dieser Befehlszeilenaufruf sollte funktionieren:

mvn dependency:purge-local-repository -DreResolve=false
Juanjo Marron
quelle
3
Gut :) Aber diese Bereinigung hängt nur vom aktuellen Projekt ab, nicht vom gesamten Repository.
Cherry
2
Das stimmt! Um das gesamte Repository zu bereinigen, würde ich manuell Verzeichnisse aus ./m2/repository entfernen, wie vor oder in neueren Versionen von Nexus (nach 2.6.4-02.) Kommentiert. Sie bieten den Link Geplante Aufgaben Link Releases From Repository aus die Kiste. Es könnte auch nützlich sein
Juanjo Marron
5
  1. Laden Sie alle tatsächlichen Abhängigkeiten Ihrer Projekte herunter

    find your-projects-dir -name pom.xml -exec mvn -f '{}' dependency:resolve
    
  2. Verschieben Sie Ihr lokales Maven-Repository an einen temporären Speicherort

    mv ~/.m2 ~/saved-m2
    
  3. Benennen Sie alle Dateien maven-metadata-central.xml * aus dem gespeicherten Repository in maven-metadata.xml * um

    find . -type f -name "maven-metadata-central.xml*" -exec rename -v -- 's/-central//' '{}' \;
    
  4. Um die geänderte Kopie des lokalen Repositorys als Spiegel einzurichten, erstellen Sie das Verzeichnis ~ / .m2 und die Datei ~ / .m2 / settings.xml mit dem folgenden Inhalt ( Benutzer durch Ihren Benutzernamen ersetzen ):

    <settings>
     <mirrors>
      <mirror>
       <id>mycentral</id>
       <name>My Central</name>
       <url>file:/home/user/saved-m2/</url>
       <mirrorOf>central</mirrorOf>
      </mirror>
     </mirrors>
    </settings>
    
  5. Lösen Sie Ihre Projektabhängigkeiten erneut:

    find your-projects-dir -name pom.xml -exec mvn -f '{}' dependency:resolve
    
  6. Jetzt haben Sie ein lokales Maven-Repository mit einem Minimum an notwendigen Artefakten. Entfernen Sie den lokalen Spiegel aus der Konfigurationsdatei und aus dem Dateisystem.

Sergey B.
quelle
Versuchte dies, bekam immer noch: "Kein Plugin für Präfix 'Abhängigkeit' im aktuellen Projekt und in den Plugin-Gruppen [org.apache.maven.plugins, org.codehaus.mojo] gefunden, verfügbar aus den Repositorys [local (/ home / user /.m2/repository), mycentral (Datei: / home / user / saved-m2 /)] "
Robert Mikes
4

Ich habe mir ein Dienstprogramm ausgedacht und auf GitHub gehostet, um alte Versionen von Bibliotheken im lokalen Maven-Repository zu bereinigen. Das Dienstprogramm entfernt bei seiner Standardausführung alle älteren Versionen von Artefakten, wobei nur die neuesten übrig bleiben. Optional können alle Snapshots, Quellen, Javadocs entfernt und auch Gruppen oder Artefakte in diesem Prozess erzwungen / ausgeschlossen werden. Diese plattformübergreifende Funktion unterstützt auch das datumsbasierte Entfernen basierend auf den Daten für den letzten Zugriff / Download.

https://github.com/techpavan/mvn-repo-cleaner

Pavan Kumar
quelle
3

Es ist mehr als 6 Jahre her, seit die Frage gestellt wurde, aber ich habe kein Tool gefunden, um mein Repository zu bereinigen. Also habe ich selbst eine in Python geschrieben, um alte Gläser loszuwerden. Vielleicht ist es für jemanden nützlich:

from os.path import isdir
from os import listdir
import re
import shutil

dry_run = False #  change to True to get a log of what will be removed
m2_path = '/home/jb/.m2/repository/' #  here comes your repo path
version_regex = '^\d[.\d]*$'


def check_and_clean(path):
    files = listdir(path)
    for file in files:
        if not isdir('/'.join([path, file])):
            return
    last = check_if_versions(files)
    if last is None:
        for file in files:
            check_and_clean('/'.join([path, file]))
    elif len(files) == 1:
        return
    else:
        print('update ' + path.split(m2_path)[1])
        for file in files:
            if file == last:
                continue
            print(file + ' (newer version: ' + last + ')')
            if not dry_run:
                shutil.rmtree('/'.join([path, file]))


def check_if_versions(files):
    if len(files) == 0:
        return None
    last = ''
    for file in files:
        if re.match(version_regex, file):
            if last == '':
                last = file
            if len(last.split('.')) == len(file.split('.')):
                for (current, new) in zip(last.split('.'), file.split('.')):
                    if int(new) > int(current):
                        last = file
                        break
                    elif int(new) < int(current):
                        break
            else:
                return None
        else:
            return None
    return last


check_and_clean(m2_path)

Es sucht rekursiv im .m2Repository und wenn es einen Katalog findet, in dem sich verschiedene Versionen befinden, werden alle bis auf die neueste Version entfernt.

Angenommen, Sie haben den folgenden Baum irgendwo in Ihrem .m2-Repo:

.
└── antlr
    ├── 2.7.2
    │   ├── antlr-2.7.2.jar
    │   ├── antlr-2.7.2.jar.sha1
    │   ├── antlr-2.7.2.pom
    │   ├── antlr-2.7.2.pom.sha1
    │   └── _remote.repositories
    └── 2.7.7
        ├── antlr-2.7.7.jar
        ├── antlr-2.7.7.jar.sha1
        ├── antlr-2.7.7.pom
        ├── antlr-2.7.7.pom.sha1
        └── _remote.repositories

Dann entfernt das Skript Version 2.7.2 von antlr und es bleibt:

.
└── antlr
    └── 2.7.7
        ├── antlr-2.7.7.jar
        ├── antlr-2.7.7.jar.sha1
        ├── antlr-2.7.7.pom
        ├── antlr-2.7.7.pom.sha1
        └── _remote.repositories

Wenn eine alte Version, die Sie aktiv verwenden, entfernt wird. Es kann einfach mit maven (oder anderen Tools, die Abhängigkeiten verwalten) wiederhergestellt werden.

Sie können ein Protokoll darüber erhalten, was entfernt werden soll, ohne es tatsächlich durch Entfernen zu entfernen dry_run = False. Die Ausgabe sieht folgendermaßen aus:

update /org/projectlombok/lombok
1.18.2 (newer version: 1.18.6)
1.16.20 (newer version: 1.18.6)

Dies bedeutet, dass die Versionen 1.16.20 und 1.18.2 von lombok entfernt und 1.18.6 unberührt bleiben.

Die Datei befindet sich auf meinem Github (die neueste Version).

Andronicus
quelle
1

Ich wollte auch alte Abhängigkeiten aus meinem Maven-Repository entfernen. Ich dachte darüber nach, nur Florians Antwort auszuführen, aber ich wollte etwas, das ich immer wieder ausführen konnte, ohne mich an ein langes Linux-Snippet zu erinnern, und ich wollte etwas mit ein wenig Konfigurierbarkeit - eher ein Programm, weniger eine Kette von Unix-Befehlen Also nahm ich die Grundidee und machte daraus ein (relativ kleines) Ruby-Programm, das alte Abhängigkeiten basierend auf ihrer letzten Zugriffszeit entfernt.

"Alte Versionen" werden nicht entfernt, aber da Sie möglicherweise zwei verschiedene aktive Projekte mit zwei verschiedenen Versionen einer Abhängigkeit haben, hätte das sowieso nicht das getan, was ich wollte. Stattdessen werden wie in Florians Antwort Abhängigkeiten entfernt, auf die in letzter Zeit nicht zugegriffen wurde.

Wenn Sie es ausprobieren möchten, können Sie:

  1. Besuchen Sie das GitHub-Repository
  2. Klonen Sie das Repository oder laden Sie die Quelle herunter
  3. Überprüfen Sie den Code optional, um sicherzustellen, dass er nicht schädlich ist
  4. Lauf bin/mvnclean

Es gibt Optionen, um das Standard-Maven-Repository zu überschreiben, Dateien zu ignorieren und das Schwellenwertdatum festzulegen. Sie können diese jedoch in der README-Datei auf GitHub lesen.

Ich werde es wahrscheinlich irgendwann als Ruby-Juwel verpacken, nachdem ich ein wenig mehr daran gearbeitet habe, was die Sache vereinfacht ( gem install mvnclean; mvnclean), wenn Sie Ruby bereits installiert und betriebsbereit haben.

Geoffrey Wiseman
quelle
Froh das zu hören. Ich denke, ich sollte mir die Mühe machen, daraus ein Juwel zu machen.
Geoffrey Wiseman
anscheinend habe ich zu früh gesprochen. Ich kenne das Muster nicht - aber einige der Gläser wurden gelöscht, obwohl ich weiß, dass ich sie kürzlich verwendet habe. Gleichzeitig blieben einige übrig.
Katholikon
Hm. Wenn Sie mir weitere Einzelheiten mitteilen können, würde ich mich gerne darum kümmern. Wenn Sie so weit kommen, melden Sie ein Problem auf GitHub an, damit ich es verfolgen kann. Scheint ziemlich konsequent für mich zu arbeiten, aber es könnte etwas Spezielles für Cygwin geben, das ich zum Beispiel untersuchen muss. Haben Sie sich die Liste angesehen, die ausgegeben wurde, bevor Sie zugestimmt haben, oder war sie zu lang, um die Überprüfung wert zu sein? Wenn Sie es noch einmal versuchen, würde es helfen, wenn ich das zuletzt verwendete Datum zur Zusammenfassung hinzufüge? ( github.com/geoffreywiseman/mvnclean/issues/10 )
Geoffrey Wiseman
Ja, sicher können Sie eine Option hinzufügen, um die Debug-Ausgabe zu sichern (jar: Datum des letzten Zugriffs) ... Ich habe das von Ihnen geöffnete Problem abonniert.
Katholikon
Aktualisiert; Schauen Sie sich das Problem an und beschreiben Sie einige Ihrer Optionen.
Geoffrey Wiseman
1

Bereinigen Sie einfach jeden Inhalt unter .m2 -> Repository-Ordner. Wenn Sie ein Projekt erstellen, werden alle Abhängigkeiten hier geladen.

In Ihrem Fall hat Ihr Projekt möglicherweise früher die alte Version einer Abhängigkeit verwendet und jetzt wird die Version aktualisiert. Bereinigen Sie daher besser den Ordner .m2 und erstellen Sie Ihr Projekt mit mvn clean install.

In diesem Ordner werden nun Abhängigkeiten mit den neuesten Versionsmodulen heruntergeladen.

Amandeep Singh Bhatia
quelle
2
Es sei denn, Sie haben Legacy-Jars manuell zum Repository hinzugefügt oder die Abhängigkeiten sind im Internet nicht mehr verfügbar. Diese Antwort ist ein bisschen gefährlich ... zumindest zuerst sichern!
Jose Manuel Gomez Alvarez
0

Sie müssen die Abhängigkeit kopieren, die Sie für das Projekt benötigen. Wenn Sie diese in der Hand haben, löschen Sie bitte alle in das <dependency>Tag eingebetteten <dependencies>Tags aus der POM.XML-Datei in Ihrem Projekt.

Nach dem Speichern der Datei sehen Sie keine Maven-Abhängigkeiten in Ihrem Libraries. Dann fügen <dependency>Sie bitte die zuvor kopierten ein.

Die erforderlichen Gläser werden von Maven automatisch heruntergeladen. Dies können Sie auch in den generierten Maven-Abhängigkeiten sehen Libraries nach dem Speichern der Datei sehen.

Vielen Dank.

Shubhasish Bhunia
quelle