912 Stimmen

Wie kann ich Maven anweisen, die neueste Version einer Abhängigkeit zu verwenden?

In Maven werden Abhängigkeiten normalerweise wie folgt eingerichtet:

<dependency>
  <groupId>wonderful-inc</groupId>
  <artifactId>dream-library</artifactId>
  <version>1.2.3</version>
</dependency>

Wenn Sie mit Bibliotheken arbeiten, die häufig veröffentlicht werden, kann das ständige Aktualisieren des <version>-Tags etwas lästig sein. Gibt es eine Möglichkeit, Maven anzuweisen, immer die neueste verfügbare Version (aus dem Repository) zu verwenden?

227 Stimmen

Ich empfehle diese Praxis (ebenso wie die Verwendung von Versionsbereichen) nicht, um die Reproduzierbarkeit der Builds zu gewährleisten. Ein Build, der plötzlich aus einem unbekannten Grund fehlschlägt, ist viel ärgerlicher als die manuelle Aktualisierung einer Versionsnummer.

17 Stimmen

@PascalThivent Manuelles Aktualisieren einer Versionsnummer in einem pom ist ein Schmerz, wenn Sie kontinuierliche Releases tun. Ich verwende das versions-Plugin in Kombination mit dem scm-Plugin, um dies zu umgehen (siehe meine Antwort).

5 Stimmen

@PascalThivent Beide sind ärgerlich, aber auf unterschiedliche Weise. Ich möchte je nach Situation zwischen beiden wählen können und nicht gezwungen werden, eines zu benutzen, weil jemand anderes entschieden hat, dass dieses besser ist.

857voto

Rich Seller Punkte 81404

HINWEIS:

Die genannten LATEST y RELEASE Metaversionen sind entfallen für Plugin-Abhängigkeiten in Maven 3 "aus Gründen der Reproduzierbarkeit der Builds". , vor über 6 Jahren. (Für reguläre Abhängigkeiten funktionieren sie immer noch einwandfrei.) Für Plugin-Abhängigkeiten beachten Sie bitte dies Maven-3-konforme Lösung .


Wenn Sie immer die neueste Version verwenden möchten, bietet Maven zwei Schlüsselwörter, die Sie als Alternative zu Versionsbereichen verwenden können. Sie sollten diese Optionen mit Vorsicht verwenden, da Sie nicht mehr die Kontrolle über die von Ihnen verwendeten Plugins/Abhängigkeiten haben.

Wenn Sie von einem Plugin oder einer Abhängigkeit abhängig sind, können Sie den Versionswert LATEST oder RELEASE verwenden. LATEST bezieht sich auf die letzte freigegebene oder Snapshot-Version eines bestimmten Artefakts, d.h. das zuletzt bereitgestellte Artefakt in einem bestimmten Repository. RELEASE bezieht sich auf die letzte Nicht-Snapshot-Version im Repository. Im Allgemeinen ist es keine gute Praxis, Software zu entwickeln, die von einer unspezifischen Version eines Artefakts abhängt. Wenn Sie Software entwickeln, möchten Sie vielleicht RELEASE oder LATEST verwenden, damit Sie die Versionsnummern nicht aktualisieren müssen, wenn eine neue Version einer Bibliothek eines Drittanbieters veröffentlicht wird. Wenn Sie Software freigeben, sollten Sie immer sicherstellen, dass Ihr Projekt von bestimmten Versionen abhängt, um das Risiko zu verringern, dass Ihr Build oder Ihr Projekt von einer Softwareversion beeinflusst wird, auf die Sie keinen Einfluss haben. Verwenden Sie LATEST und RELEASE, wenn überhaupt, nur mit Vorsicht.

Siehe die POM Syntax Abschnitt des Maven Buches für weitere Einzelheiten. Oder siehe dieses Dokument auf Abhängige Versionsspannen , wobei:

  • Eine eckige Klammer ( [ & ] ) bedeutet "geschlossen" (einschließlich).
  • Eine Klammer ( ( & ) ) bedeutet "offen" (exklusiv).

Hier ein Beispiel, das die verschiedenen Optionen veranschaulicht. Im Maven Repository hat com.foo:my-foo die folgenden Metadaten:

<?xml version="1.0" encoding="UTF-8"?><metadata>
  <groupId>com.foo</groupId>
  <artifactId>my-foo</artifactId>
  <version>2.0.0</version>
  <versioning>
    <release>1.1.1</release>
    <versions>
      <version>1.0</version>
      <version>1.0.1</version>
      <version>1.1</version>
      <version>1.1.1</version>
      <version>2.0.0</version>
    </versions>
    <lastUpdated>20090722140000</lastUpdated>
  </versioning>
</metadata>

Wenn eine Abhängigkeit von diesem Artefakt erforderlich ist, haben Sie die folgenden Optionen (andere Versionsbereiche können natürlich angegeben werden, ich zeige hier nur die relevanten):

Geben Sie eine genaue Version an (wird immer zu 1.0.1 aufgelöst):

<version>[1.0.1]</version>

Deklarieren Sie eine explizite Version (wird immer auf 1.0.1 aufgelöst, es sei denn, eine Kollision tritt auf, dann wird Maven eine passende Version auswählen):

<version>1.0.1</version>

Deklarieren Sie einen Versionsbereich für alle 1.x (wird derzeit zu 1.1.1 aufgelöst):

<version>[1.0.0,2.0.0)</version>

Deklarieren Sie einen unbefristeten Versionsbereich (wird zu 2.0.0 aufgelöst):

<version>[1.0.0,)</version>

Deklarieren Sie die Version als LATEST (wird zu 2.0.0 aufgelöst) (entfernt von Maven 3.x)

<version>LATEST</version>

Deklarieren Sie die Version als RELEASE (wird zu 1.1.1 aufgelöst) (entfernt aus maven 3.x):

<version>RELEASE</version>

Beachten Sie, dass Ihre eigenen Einsätze standardmäßig den "latest"-Eintrag in den Maven-Metadaten aktualisieren, aber um den "release"-Eintrag zu aktualisieren, müssen Sie das "release-profile" aus dem Maven super POM . Sie können dies entweder mit "-Prelease-profile" oder "-DperformRelease=true" tun.


Es sollte betont werden, dass jeder Ansatz, der es Maven erlaubt, die Abhängigkeitsversionen (LATEST, RELEASE und Versionsbereiche) auszuwählen, zu Problemen bei der Build-Zeit führen kann, da spätere Versionen ein anderes Verhalten aufweisen können (z.B. hat das Abhängigkeits-Plugin in der Vergangenheit einen Standardwert von true auf false geändert, mit verwirrenden Ergebnissen).

Daher ist es in der Regel sinnvoll, in Freigaben genaue Versionen zu definieren. Als Tims Antwort weist darauf hin, dass die maven-versions-plugin ist ein praktisches Werkzeug zur Aktualisierung von Abhängigkeitsversionen, insbesondere der versions:use-latest-versions y versions:use-latest-releases Ziele.

2 Stimmen

Ich denke, dass LATEST/RELEASE sehr wichtig für Plugins ist, die Bereitstellungsfunktionen bieten. Zum Beispiel verwenden wir ein Plugin, das neue Versionen von Artefakten auf unseren Servern bereitstellt. Wenn sich die Server ändern, veröffentlichen wir eine neue Version des Plugins und alle Projekte, die dieses Plugin verwenden, müssen manuell aktualisiert werden, um die neue Version des Plugins zu verwenden.

9 Stimmen

@RichSeller hey Rich; Ich habe ein wenig Zeit damit verbracht, bevor ich herausfand, dass dies in Maven 3.0 nicht mehr verfügbar ist ;) Könntest du in Erwägung ziehen, die Antwort so zu bearbeiten, dass sie mit einem Update beginnt, in dem die Maven 3.0-Abweichung angegeben wird? Herzlichen Dank!

6 Stimmen

Ich glaube, ein gutes Gleichgewicht wäre es, die Hauptversion zu sperren, aber die neueste Nebenversion (oder Patch) zu erhalten (je nachdem, welche Version nur für Fehlerbehebungen in dem Artifcat verwendet wird, von dem Sie abhängig sind). Mit der aktuellen Syntax scheint dies nur mit einem Bereich wie (Anmerkung: beginnt mit Klammern und endet mit Parens) möglich zu sein: [1.1,2.0)

429voto

Tim Punkte 19225

Ich weiß, dass dieses Thema alt ist, aber wenn ich die Frage und die vom OP gelieferte Antwort lese, scheint es, dass die Maven-Versionen-Plugin wäre vielleicht sogar eine bessere Antwort auf seine Frage gewesen:

Insbesondere die folgenden Ziele könnten von Nutzen sein:

  • versions:use-latest-versions sucht im pom nach allen Versionen die eine neuere Version waren und ersetzt sie durch die neueste Version.
  • versions:use-latest-releases sucht im pom nach allen Nicht-SNAPSHOT Versionen, die eine neuere Version waren und ersetzt sie durch die neueste Version.
  • versions:update-properties aktualisiert Eigenschaften, die in einer Projekt definierten Eigenschaften, so dass sie der der neuesten verfügbaren Version von bestimmten Abhängigkeiten entsprechen. Dies kann nützlich sein, wenn eine Reihe von Abhängigkeiten alle auf eine Version festgelegt werden müssen.

Die folgenden weiteren Ziele sind ebenfalls vorgesehen:

  • versions:display-dependency-updates scannt die Abhängigkeiten eines Projekts und erstellt einen Bericht über diejenigen Abhängigkeiten, die über neuere Versionen verfügbar sind.
  • versions:display-plugin-updates scannt die Plugins eines Projekts und erstellt einen Bericht über diejenigen Plugins für die neuere Versionen verfügbar sind.
  • versionen:update-parent aktualisiert den übergeordneten Abschnitt eines Projekts so dass er auf die neueste verfügbare verfügbare Version verweist. Zum Beispiel, wenn Sie ein unternehmensweites Root-POM verwenden, kann dieses Ziel hilfreich sein, wenn Sie sicherstellen müssen sicherstellen müssen, dass Sie die neueste Version des firmeneigenen Root-POMs verwenden.
  • versionen:update-child-modules aktualisiert den übergeordneten Abschnitt der untergeordneten Module eines Projekts, so dass die Version mit der Version des aktuellen Projekts entspricht. Zum Beispiel, wenn Sie einen Aggregator pom haben, der auch der Elternteil für die Projekte ist, die er aggregiert und die Versionen der Kinder und übergeordneten Versionen nicht mehr synchron sind, kann dieses mojo kann dabei helfen, die Versionen der Kind-Module zu korrigieren. (Beachten Sie, dass Sie möglicherweise Maven mit der Option -N aufrufen, um um dieses Ziel zu erreichen, wenn Ihr Projekt so stark beschädigt ist, dass es nicht gebaut werden kann, weil die Version nicht bauen kann).
  • versionen:sperren-schnappschüsse durchsucht das Pom für alle -SNAPSHOT Versionen und ersetzt sie durch die aktuellen Zeitstempel der Version dieses -SNAPSHOT, z.B. -20090327.172306-4
  • Versionen:Schnappschüsse freischalten sucht im Pom nach allen Zeitstempeln gesperrten Snapshot-Versionen und ersetzt sie durch -SNAPSHOT.
  • versions:resolve-ranges findet Abhängigkeiten anhand von Versionsbereichen und löst den Bereich in die spezifische Version auf, die verwendet wird.
  • versions:use-releases sucht im pom nach allen -SNAPSHOT Versionen die veröffentlicht wurden, und ersetzt sie durch die entsprechende Release Version.
  • versions:use-next-releases durchsucht das Pom nach allen Nicht-SNAPSHOT Versionen, die eine neuere Version waren und ersetzt sie durch die nächste Release-Version.
  • versionen:benutze-nächste-versionen sucht im pom nach allen Versionen die eine neuere Version gewesen sind und ersetzt sie durch die nächste Version.
  • versionen:commit entfernt die pom.xml.versionsBackup-Dateien. Formulare die eine Hälfte des eingebauten "Poor Man's SCM".
  • Versionen:revert stellt die pom.xml-Dateien aus den pom.xml.versionsBackup-Dateien. Formulare eine Hälfte des eingebauten "Poor Man's SCM".

Ich dachte nur, ich füge sie für künftige Hinweise bei.

10 Stimmen

Was ist in diesem Zusammenhang der Unterschied zwischen "Release" und "Version"?

2 Stimmen

@BenNoland, ich glaube, der Unterschied in diesem Fall ist, dass die nächste Version nicht unbedingt ein Release-Artefakt sein muss. Z.B. bei einem Artefakt mit den Versionen 1.0.0-SNAPSHOT, 1.0.0 und 1.0.1-SNAPSHOT und einer pom-Referenz auf 1.0.0-SNAPSHOT werden versions:next-versions und versions:next-releases auf 1.0.0 aufgelöst, während versions:latest-versions und versions:latest-releases auf 1.0.1-SNAPSHOT bzw. 1.0.0 aufgelöst werden.

3 Stimmen

Es ist nicht hilfreich, alle möglichen und nicht miteinander verbundenen Ziele auszudrucken.

175voto

Martin Klinke Punkte 7148

Schauen Sie sich bitte an diese Seite (Abschnitt "Abhängigkeitsversionsbereiche"). Was Sie vielleicht tun möchten, ist etwas wie

<version>[1.2.3,)</version>

Diese Versionsbereiche sind in Maven2 implementiert.

4 Stimmen

Sie sollten sich vielleicht genauer ansehen, wie Maven Versionsnummern vergleicht - wenn Sie nicht einem strengen Muster entsprechen, vergleicht Maven als Strings und nicht als Zahlen.

0 Stimmen

Diese Seite ist auf Codehaus und beschreibt sich selbst als Dinge, "die noch nicht für Maven 2.0 implementiert wurden"... Die Maven Dokumentation selbst sagt nichts über Versionsbereiche. Übersehe ich etwas? Wann wurden Versionsbereiche eingeführt? Wo sind sie in der offiziellen Dokumentation beschrieben?

6 Stimmen

Sie liegen falsch, Versionsbereich bedeutet, dass alle Versionen von 1.2.3 bis höher in Ordnung sind. Dies ist nicht die neueste Version überhaupt.

95voto

Adam Gent Punkte 45977

Im Gegensatz zu anderen denke ich, dass es viele Gründe gibt, warum Sie immer das Neueste wollen Version. Vor allem, wenn Sie kontinuierliche Bereitstellung tun (wir haben manchmal wie 5 Releases an einem Tag) und nicht wollen, um ein Multi-Modul-Projekt zu tun.

Was ich tue, ist Hudson/Jenkins machen die folgenden für jeden Build:

mvn clean versions:use-latest-versions scm:checkin deploy -Dmessage="update versions" -DperformRelease=true

Das heißt, ich verwende das Versions-Plugin und das scm-Plugin, um die Abhängigkeiten zu aktualisieren, und checke es dann in die Versionskontrolle ein. Ja, ich lasse mein CI SCM-Check-Ins durchführen (was Sie ohnehin für das Maven Release Plugin tun müssen).

Sie sollten das Versions-Plugin so einrichten, dass es nur das aktualisiert, was Sie wollen:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>versions-maven-plugin</artifactId>
    <version>1.2</version>
    <configuration>
        <includesList>com.snaphop</includesList>
        <generateBackupPoms>false</generateBackupPoms>
        <allowSnapshots>true</allowSnapshots>
    </configuration>
</plugin>

Ich verwende das Release-Plugin für die Freigabe, das sich um -SNAPSHOT kümmert und überprüft, ob es eine Release-Version von -SNAPSHOT gibt (was wichtig ist).

Wenn Sie tun, was ich tue, erhalten Sie die neueste Version für alle Snapshot-Builds und die neueste Release-Version für Release-Builds. Ihre Builds werden auch reproduzierbar sein.

更新情報

Mir ist aufgefallen, dass in einigen Kommentaren nach den Besonderheiten dieses Arbeitsablaufs gefragt wurde. Ich möchte sagen, dass wir diese Methode nicht mehr verwenden und der Hauptgrund dafür ist, dass das Maven-Versionen-Plugin fehlerhaft ist und im Allgemeinen von Natur aus mangelhaft ist.

Es ist fehlerhaft, denn um das Versions-Plugin zum Anpassen von Versionen auszuführen, müssen alle vorhandenen Versionen vorhanden sein, damit das pom korrekt ausgeführt werden kann. Das heißt, das Versions-Plugin kann nicht auf die neueste Version von irgendetwas aktualisieren, wenn es die im Pom referenzierte Version nicht finden kann. Dies ist eigentlich ziemlich ärgerlich, da wir oft alte Versionen aus Speicherplatzgründen bereinigen.

Sie benötigen ein separates Tool von Maven, um die Versionen anzupassen (damit Sie nicht von der pom-Datei abhängig sind, um korrekt zu arbeiten). Ich habe ein solches Tool in der bescheidenen Sprache Bash geschrieben. Das Skript aktualisiert die Versionen wie das Versions-Plugin und checkt das Pom zurück in die Versionskontrolle. Es läuft auch etwa 100x schneller als das mvn versions plugin. Leider ist es nicht in einer Art und Weise für die öffentliche Nutzung geschrieben, aber wenn die Leute daran interessiert sind, könnte ich es so machen und es in einem Gist oder Github setzen.

Um auf den Arbeitsablauf zurückzukommen, nach dem in einigen Kommentaren gefragt wurde: Das ist es, was wir tun:

  1. Wir haben etwa 20 Projekte in ihren eigenen Repositories mit eigenen Jenkins-Jobs
  2. Bei der Veröffentlichung wird das Maven Release Plugin verwendet. Der Arbeitsablauf ist in der Dokumentation des Plugins beschrieben. Das Maven-Release-Plugin ist irgendwie ätzend (und das ist nett gemeint), aber es funktioniert. Eines Tages planen wir, diese Methode durch etwas Optimaleres zu ersetzen.
  3. Wenn eines der Projekte veröffentlicht wird, führt Jenkins einen speziellen Job aus, den wir den Update-All-Versions-Job nennen (woher Jenkins weiß, dass es sich um eine Veröffentlichung handelt, ist kompliziert, zum Teil weil das Maven-Jenkins-Release-Plugin auch ziemlich beschissen ist).
  4. Die Aufgabe "Alle Versionen aktualisieren" kennt alle 20 Projekte. Es ist eigentlich ein Aggregator pom, um genau zu sein, mit allen Projekten im Modulbereich in der Reihenfolge der Abhängigkeiten. Jenkins führt unser magisches groovy/bash foo aus, das alle Projekte abruft, die Versionen auf den neuesten Stand bringt und dann die Poms eincheckt (wiederum in Abhängigkeitsreihenfolge basierend auf dem Modulbereich).
  5. Für jedes Projekt, bei dem sich das Pom geändert hat (aufgrund einer Versionsänderung in einer Abhängigkeit), wird es eingecheckt, und dann pingen wir sofort Jenkins an, um den entsprechenden Job für dieses Projekt auszuführen (dies dient dazu, die Reihenfolge der Build-Abhängigkeiten beizubehalten, da man sonst der Gnade des SCM Poll Schedulers ausgeliefert ist).

An diesem Punkt bin ich der Meinung, dass es gut ist, die Freigabe- und Autoversion als separates Tool von der allgemeinen Version zu haben.

Nun könnte man meinen, dass Maven wegen der oben genannten Probleme ziemlich scheiße ist, aber das wäre tatsächlich ziemlich schwierig mit einem Build-Tool, das keine einfach zu analysierende Deklaration hat ausziehbar Syntax (auch XML genannt).

In der Tat fügen wir benutzerdefinierte XML-Attribute durch Namespaces hinzu, um Hinweise auf Bash/Groovy-Skripte zu geben (z. B. "Diese Version nicht aktualisieren").

5 Stimmen

Danke, dass Sie eine Motivation (kontinuierliche Bereitstellung) in Ihre Antwort aufgenommen haben.

13 Stimmen

Ich denke, der wichtige Punkt hier ist, dass Builds mit dieser Methode reproduzierbar sind, während sie es bei der Verwendung von Versionsbereichen oder -LATEST nicht sind!

0 Stimmen

Ich möchte die Lösung mit einem externen Tool, das Änderungen am Projekt pom vor dem Ausführen von Build zu zweit. Wir sind auch mit diesem Ansatz als Version-Range-Plugin ist inhärent fehlerhaft zum Beispiel unter Berücksichtigung von Daten und nicht nur Versionen.

46voto

mkobit Punkte 38986

Die Syntax für die Abhängigkeiten befindet sich in der Abhängigkeit Version Anforderungsspezifikation Dokumentation. Hier ist sie der Vollständigkeit halber:

Abhängigkeiten version Element definieren Versionsanforderungen, die zur Berechnung der effektiven Abhängigkeitsversion verwendet werden. Die Versionsanforderungen haben die folgende Syntax:

  • 1.0 : "Weiche" Anforderung auf 1.0 (nur eine Empfehlung, wenn sie mit allen anderen Bereichen für die Abhängigkeit übereinstimmt)
  • [1.0] : "Harte" Anforderung an 1.0
  • (,1.0] : x <= 1.0
  • [1.2,1.3] : 1.2 <= x <= 1.3
  • [1.0,2.0) : 1.0 <= x < 2.0
  • [1.5,) : x >= 1.5
  • (,1.0],[1.2,) x <= 1,0 oder x >= 1,2; mehrere Sätze werden durch Komma getrennt
  • (,1.1),(1.1,) : Dies schließt 1.1 aus (zum Beispiel, wenn bekannt ist, dass es nicht in Kombination mit dieser Bibliothek funktioniert)

In Ihrem Fall könnten Sie etwa so vorgehen <version>[1.2.3,)</version>

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X