Vererbung der Maven-Projektversion - muss ich die übergeordnete Version angeben?

188

Ich habe zwei Projekte: Übergeordnetes Projekt: A, Unterprojekt: B.

A / pom.xml:

<groupId>com.dummy.bla</groupId>
<artifactId>parent</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>pom</packaging>

Und in B / pom.xml habe ich:

    <parent>
        <groupId>com.dummy.bla</groupId>
        <artifactId>parent</artifactId>
        <version>0.1-SNAPSHOT</version>     
    </parent>

    <groupId>com.dummy.bla.sub</groupId>
    <artifactId>kid</artifactId>

Ich will B die Version von den Eltern erben, so dass der einzige Ort in meinem Fall habe ich setzen müssen 0.1-SNAPSHOTist A/pom.xml. Aber wenn ich das entfernen <version>0.1-SNAPSHOT</version>von B/pom.xmlunter dem Abschnitt Elternteil, klagt Maven über die fehlende Version für die Eltern.

Gibt es eine Möglichkeit, die ich nur verwenden kann, ${project.version}oder so etwas, um zu vermeiden, dass ich 01.-SNAPSHOTbeide Poms habe?

Shengjie
quelle
4
Sie müssen leider auf Maven 3.1 warten.
Wahrnehmung
1
Der obige Link wurde verschoben. Der endgültige Status war "Geschlossen / Wird nicht repariert" behoben Issues.apache.org/jira/browse/MNG-624
Jocull

Antworten:

86

EDIT: Seit Maven 3.5.0 gibt es dafür eine schöne Lösung mit ${revision}Platzhalter. Siehe FrVaBe Antwort für weitere Einzelheiten. Für frühere Maven-Versionen siehe meine ursprüngliche Antwort unten.


Nein, gibt es nicht. Sie müssen immer die Version des Elternteils angeben. Glücklicherweise wird es als Modulversion vererbt, was in den meisten Fällen wünschenswert ist. Darüber hinaus wird die Versionsdeklaration dieses übergeordneten Elements automatisch vom Maven Release Plugin angehoben. Daher ist es kein Problem, dass Sie die Version an zwei Stellen haben, solange Sie das Maven Release Plugin zum Freigeben oder nur zum Beheben von Versionen verwenden.

Beachten Sie, dass es einige Fälle gibt, in denen dieses Verhalten tatsächlich in Ordnung ist und mehr Flexibilität bietet, die Sie möglicherweise benötigen. Manchmal möchten Sie einige Versionen der vorherigen Eltern zum Erben verwenden, dies ist jedoch kein Mainstream-Fall.

Michał Kalinowski
quelle
3
Jetzt können Sie den ${revision}Platzhalter dafür verwenden. Siehe meine Antwort ;-)
FrVaBe
2
Dies ist jetzt veraltet - überprüfen Sie @ FrVaBes Antwort hier: stackoverflow.com/a/51969067/514483
robd
@FrVaBe was ist, wenn wir Eltern mit verschiedenen Versionen verschachtelt haben? Wir können dort keine $ {revision} -Eigenschaft verwenden, es reicht nicht aus.
Halil
@halil Bei der Frage geht es darum, eine Version von einem Elternteil zu erben, mit dem Ziel, dieselbe Version in zwei Artefakten zu haben. Wenn Sie unterschiedliche Eltern mit unterschiedlichen Versionen haben (in einer Vererbungshierarchie), werden Sie wahrscheinlich nicht alle zur gleichen Version machen. Ich verstehe den Kommentar daher nicht vollständig.
FrVaBe
86

Maven ist nicht dafür ausgelegt, auf diese Weise zu funktionieren, aber es gibt eine Problemumgehung, um dieses Ziel zu erreichen (möglicherweise müssen Sie es mit Nebenwirkungen versuchen). Der Trick besteht darin, das untergeordnete Projekt anzuweisen, sein übergeordnetes Projekt über seinen relativen Pfad zu finden untergeordnete anzuweisen, Element und nicht über seine reinen Maven-Koordinaten zu finden, und zusätzlich die Versionsnummer in einer Eigenschaft zu externalisieren:

Eltern pom

<groupId>com.dummy.bla</groupId>
<artifactId>parent</artifactId>
<version>${global.version}</version>
<packaging>pom</packaging>

<properties>
   <!-- Unique entry point for version number management --> 
   <global.version>0.1-SNAPSHOT</global.version>
</properties>

Kind pom

<parent>
   <groupId>com.dummy.bla</groupId>
   <artifactId>parent</artifactId>
   <version>${global.version}</version>
   <relativePath>..</relativePath>    
</parent>

<groupId>com.dummy.bla.sub</groupId>
<artifactId>kid</artifactId>

Ich habe diesen Trick für eine Weile für eines meiner Projekte verwendet, ohne ein spezifisches Problem, außer der Tatsache, dass Maven zu Beginn des Builds viele Warnungen protokolliert, was nicht sehr elegant ist.

BEARBEITEN

Scheint, dass Maven 3.0.4 eine solche Konfiguration nicht mehr zulässt.

Yanflea
quelle
2
Ja, ich fürchte, Maven ist nicht dafür ausgelegt, so zu funktionieren. Bleib einfach beim Einfügen der Versionen in die Sub-Datei pom.xml. Das Maven Release Plugin kümmert sich sowieso nicht wirklich um die Versionen dort.
Shengjie
7
für 3.0.5 funktioniert ok. Sie sollten jedoch <Eigenschaften> ganz oben platzieren.
Ses
7
Es funktioniert in 3.2.3. Der Speicherort von <Eigenschaften> spielt keine Rolle. Sie erhalten jedoch eine Warnung:'version' contains an expression but should be a constant.
Kapex
4
Bitte seien Sie vorsichtig damit. Dies funktioniert nicht, wenn Ihr Projekt von einem anderen Projekt referenziert wird. Die Eigenschaft wird nicht aufgelöst und buchstäblich behandelt (dh $ {my.version}). Dies führt zu einem Fehler beim Auflösen von Abhängigkeiten.
Spekdrum
2
Ich benutze dies jetzt auch schon eine ganze Weile und es funktioniert gut (derzeit mit Maven 3.3.9) für ein einzelnes Multi-Modul-Projekt. Sobald Ihr Projekt jedoch von einem anderen Projekt abhängig wird, werden die Dinge wirklich schwierig. Ich schlage wirklich vor, den von @pay unten vorgeschlagenen Vorschlag zu übernehmen.
Genialer
80

Der einfachste Weg, um Versionen IMO zu aktualisieren:

$ mvn versions:set -DgenerateBackupPoms=false

(Tun Sie das in Ihrem Root / Parent Pom Ordner).

Ihre POMs werden analysiert und Sie werden gefragt, welche Version Sie einstellen möchten.

pai
quelle
17
Sie können auch -DnewVersion = {versionToBeUpdated} hinzufügen, um eine interaktive Eingabe zu vermeiden.
Mukesh
1
Ich denke, dies ist die beste Antwort. Sie automatisiert Versionsänderungen, ohne Teilprojekte zu beschädigen (auf die Sie ohne das übergeordnete POM nicht verweisen könnten).
Tarek
Jep! Das ist die Antwort. 🙌
aaiezza
Wenn sich die untergeordnete und die übergeordnete POM-Version anfangs unterscheiden, aktualisieren Sie sie zuerst entsprechend. mvn versions:update-child-modules Andernfalls werden alle untergeordneten Modul-POM-Versionen übersprungen.
Gautam Tadigoppula
74

Seit Maven 3.5.0 können Sie dafür den ${revision}Platzhalter verwenden. Die Verwendung ist hier dokumentiert: Maven CI Friendly Versions .

Kurz gesagt, der übergeordnete Pom sieht folgendermaßen aus (zitiert aus der Apache-Dokumentation):

<project>
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.apache</groupId>
    <artifactId>apache</artifactId>
    <version>18</version>
  </parent>
  <groupId>org.apache.maven.ci</groupId>
  <artifactId>ci-parent</artifactId>
  <name>First CI Friendly</name>
  <version>${revision}</version>
  ...
  <properties>
    <revision>1.0.0-SNAPSHOT</revision>
  </properties>
  <modules>
    <module>child1</module>
    ..
  </modules>
</project>

und das Kind pom so

<project>
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.apache.maven.ci</groupId>
    <artifactId>ci-parent</artifactId>
    <version>${revision}</version>
  </parent>
  <groupId>org.apache.maven.ci</groupId>
  <artifactId>ci-child</artifactId>
   ...
</project>

Sie auch müssen die Verwendung Flatten Maven Plugin pom Dokumente mit der dedizierten Versionsnummer für die Bereitstellung einbezogen zu erzeugen. Das HowTo ist in der verknüpften Dokumentation dokumentiert.

Auch @khmarbaise hat einen schönen Blob-Beitrag über diese Funktion geschrieben: Maven: POM-Dateien ohne Version?

FrVaBe
quelle
Ich habe mein Projekt wie von Ihnen beschrieben konfiguriert, aber ohne das "Flatten Maven Plugin" und es scheint wie erwartet zu funktionieren. Ist dies möglich? Ich habe auch einen Fehler mit Maven 3.2.1 bekommen, aber Maven 3.3.9+ scheint gut zu funktionieren.
Max
@Max Es hängt davon ab, was Sie als "Arbeit wie erwartet" definieren. Ich denke, der Build wird bestanden, aber die Installation / Bereitstellung in einem Repository ist wahrscheinlich keine gute Idee, da das
untergeordnete POM
Ich verwende <version> $ {revision} </ version> im übergeordneten pom mit der Standardeigenschaft (<properties> <version> 0.1-default </ version> </ property>. Untergeordnete Poms verwenden auch <version> $ {revision} < / version>. Ich verwende "mvn clean install -Drevision = 0.1. $ {bamboo.buildNumber}". Wenn ich die Protokolle der Bereitstellung scanne, ist alles auf 0.1.820 eingestellt und 0.1-default ist nicht einmal in den Protokollen (820) ist die buildNumber). Wenn ich das resultierende JAR scanne, sehe ich "Manifestation-Version: 0.1.820" im Manifest und auch "version = 0.1.820" in einer pom.properties-Datei. Die pom-Datei selbst hat <version> $ {revision} </ version>. Also ich denke es ist in Ordnung?
Max
1
@Max Versuchen Sie, ein JAR, in dem sich die Version ${revision} im POM (im Maven-Repository) befindet, als Abhängigkeit in einem anderen Projekt aufzulösen. Ich denke nicht, dass dies funktionieren wird.
FrVaBe
Dies ist nützlich, außer wenn ich eine Veröffentlichung mache. Das ersetzt ${revision}im Versions-Tag durch die neue Version
Mike D
21

Wie Yanflea erwähnte, gibt es einen Weg, dies zu umgehen.

In Maven 3.5.0 können Sie die Version auf folgende Weise aus dem übergeordneten Projekt übertragen:

Übergeordnete POM.xml

<project ...>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.mydomain</groupId>
    <artifactId>myprojectparent</artifactId>
    <packaging>pom</packaging>
    <version>${myversion}</version>
    <name>MyProjectParent</name>

    <properties>
        <myversion>0.1-SNAPSHOT</myversion>
    </properties>

    <modules>
        <module>modulefolder</module>
    </modules>
    ...
</project>

Modul POM.xml

<project ...>
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.mydomain</groupId>
        <artifactId>myprojectmodule</artifactId>
        <version>${myversion}</version> <!-- This still needs to be set, but you can use properties from parent -->
    </parent>

    <groupId>se.car_o_liner</groupId>
    <artifactId>vinno</artifactId>
    <packaging>war</packaging>
    <name>Vinno</name>
    <!-- Note that there's no version specified; it's inherited from parent -->
    ...
</project>

Es steht Ihnen frei, zu dem zu wechseln myversion, was Sie möchten, das keine reservierte Eigenschaft ist.

eFox
quelle
3
Wenn Sie auf ein Modul aus einem anderen Projekt verweisen, löst Maven die Eigenschaft nicht auf. Ist das normal?
LeoLozes
Ich glaube, dass diese Frage einen eigenen Eintrag verdient und nicht in einem Kommentar wie diesem enthalten ist. Ohne Ihren Code zu sehen, kann ich nur wild raten.
eFox
@LeoLozes Haben Sie Ihr Problem gelöst (Aktualisierungsmodul aus einem anderen Projekt)?
Morteza Malvandi
@ MortezaMalvandi ja! Meine Antwort ist unten :)
LeoLozes
2
Maven 3.6.0 warnt vor dieser Konfiguration: "Es wird dringend empfohlen, diese Probleme zu beheben, da sie die Stabilität Ihres Builds gefährden." "Aus diesem Grund unterstützen zukünftige Maven-Versionen möglicherweise nicht mehr das Erstellen solcher fehlerhaften Projekte."
d2k2
17

Sie könnten auch verwenden:

$ mvn release:update-versions -DdevelopmentVersion={version}

um die Versionsnummern in Ihren POMs zu aktualisieren.

Jerry Jin
quelle
10

Die Antwort von eFox funktionierte für ein einzelnes Projekt, aber nicht, wenn ich auf ein Modul von einem anderen verwies (die Datei pom.xml wurde weiterhin in meiner .m2mit der Eigenschaft anstelle der Version gespeichert ).

Es funktioniert jedoch, wenn Sie es mit dem kombinieren flatten-maven-plugin, da es die Poms mit der richtigen Version generiert, nicht mit der Eigenschaft.

Die einzige Option, die ich in der Plug-In-Definition geändert habe, ist die outputDirectory, sie ist standardmäßig leer, aber ich bevorzuge sie target, die in meiner .gitignoreKonfiguration festgelegt ist:

<plugin>
   <groupId>org.codehaus.mojo</groupId>
   <artifactId>flatten-maven-plugin</artifactId>
   <version>1.0.1</version>
   <configuration>
      <updatePomFile>true</updatePomFile>
      <outputDirectory>target</outputDirectory>
   </configuration>
   <executions>
      <execution>
         <id>flatten</id>
         <phase>process-resources</phase>
         <goals>
            <goal>flatten</goal>
         </goals>
      </execution>
   </executions>
</plugin>

Die Plug-In-Konfiguration befindet sich in der übergeordneten Datei pom.xml

LeoLozes
quelle
0
<parent>
    <groupId>com.dummy.bla</groupId>
    <artifactId>parent</artifactId>
    <version>0.1-SNAPSHOT</version>     
 </parent>

 <groupId>com.dummy.bla.sub</groupId>
 <artifactId>kid</artifactId>

Sie meinen, Sie möchten die Version aus dem übergeordneten Block von Bs POM entfernen. Ich denke, Sie können dies nicht tun. Die Gruppen-ID, die Artefakt-ID und die Version haben die POM-Koordinaten der Eltern angegeben. Was Sie weglassen können, ist die untergeordnete Version.

Yu Chai
quelle