Dziedziczenie wersji projektu Maven - czy muszę określać wersję nadrzędną?


189

Mam dwa projekty: Projekt nadrzędny: A, Podprojekt: B

A / pom.xml:

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

A w B / pom.xml mam:

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

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

Chcę, aby B odziedziczył wersję po rodzicu, więc jedynym miejscem w moim przypadku, które muszę podać, 0.1-SNAPSHOTjest A/pom.xml. Ale jeśli usunę <version>0.1-SNAPSHOT</version>spod B/pom.xmlsekcji nadrzędnej, maven narzeka na brakującą wersję dla rodzica.

Czy jest jakiś sposób, którego mogę użyć ${project.version}lub coś takiego, aby uniknąć stosowania 01.-SNAPSHOTobu poms?


4
Obawiam się, że będziesz musiał poczekać na Maven 3.1.
— Postrzeganie



1
Powyższy link został przeniesiony. Ostateczny status to „Zamknięty / nie naprawi
— dniu

Odpowiedzi:


86

EDYCJA: Od wersji Maven 3.5.0 istnieje dobre rozwiązanie tego problemu za pomocą ${revision}symbolu zastępczego. Szczegółowe informacje można znaleźć w odpowiedzi FrVaBe . W przypadku poprzednich wersji Maven zobacz moją oryginalną odpowiedź poniżej.


Nie, nie ma. Zawsze musisz podać wersję rodzica. Na szczęście jest dziedziczona jako wersja modułu, co jest pożądane w większości przypadków. Co więcej, deklaracja wersji tego rodzica jest automatycznie zderzana przez wtyczkę Maven Release Plugin, więc - w rzeczywistości - nie jest problemem, że masz wersję w 2 miejscach, o ile używasz wtyczki Maven Release Plugin do wydawania lub po prostu wypuszczania wersji.

Zauważ, że w niektórych przypadkach takie zachowanie jest całkiem OK i zapewnia większą elastyczność, której możesz potrzebować. Czasami chcesz użyć części poprzedniej wersji rodzica do dziedziczenia, jednak nie jest to główny nurt.


3
Teraz możesz do tego użyć symbolu ${revision}zastępczego. Zobacz moją odpowiedź ;-)
— FrVaBe

2
To jest już nieaktualne - sprawdź odpowiedź @ FrVaBe tutaj: stackoverflow.com/a/51969067/514483
— robd

@FrVaBe co zrobić, jeśli mamy zagnieżdżonych rodziców w różnych wersjach? Nie możemy tam użyć jednej właściwości $ {rewizja}, to nie wystarczy.
— halil

@halil Pytanie dotyczy dziedziczenia wersji od rodzica w celu uzyskania tej samej wersji w dwóch artefaktach. Jeśli masz różnych rodziców z różnymi wersjami (w hierarchii dziedziczenia), prawdopodobnie nie utworzysz ich wszystkich w tej samej wersji. Dlatego nie rozumiem w pełni komentarza.
— FrVaBe,

86

Maven nie jest zaprojektowany do działania w ten sposób, ale istnieje obejście tego problemu (być może z efektami ubocznymi będziesz musiał spróbować). Sztuczka polega na tym, aby powiedzieć dziecku, aby znalazł swojego rodzica poprzez ścieżkę względną zamiast współrzędnych czystego mavu, a ponadto uzewnętrznić numer wersji we właściwości:

Parent 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>

Dziecko 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>

Użyłem tej sztuczki przez pewien czas w jednym z moich projektów, bez żadnego konkretnego problemu, z wyjątkiem faktu, że maven zapisuje wiele ostrzeżeń na początku kompilacji, co nie jest zbyt eleganckie.

EDYTOWAĆ

Wygląda na to, że maven 3.0.4 nie pozwala już na taką konfigurację.


2
tak, obawiam się, że maven nie jest zaprojektowany do działania w ten sposób, lepiej po prostu trzymaj się wersji w pliku sub pom.xml. W każdym razie wtyczka maven release nie dba o dostępne tam wersje.
— Shengjie

7
dla 3.0.5 działa dobrze. powinieneś umieścić <properties> na samej górze.
— ses

7
Działa w 3.2.3. Lokalizacja <właściwości> nie ma znaczenia. Dostaniesz jednak ostrzeżenie:'version' contains an expression but should be a constant.
— kapex

4
Bądź ostrożny z tym. To nie działa, gdy do twojego projektu odwołuje się inny projekt. Właściwość nie zostanie rozwiązana i będzie traktowana dosłownie (tj. $ {My.version}). Doprowadzi to do niepowodzenia podczas rozwiązywania zależności.
— spekdrum

2
Używam tego również od dłuższego czasu i działa dobrze (obecnie z maven 3.3.9) dla pojedynczego projektu wielomodułowego. Jednak gdy tylko twój projekt stanie się zależny od innego projektu, sytuacja staje się naprawdę trudna. Naprawdę sugeruję przyjęcie sugestii zaproponowanej przez @pay poniżej.
— genialny

81

Najprostszym sposobem na aktualizację wersji IMO:

$ mvn versions:set -DgenerateBackupPoms=false

(zrób to w folderze pom / root pom).

Twoje POM są analizowane i pojawia się pytanie, którą wersję ustawić.


17
Możesz także dodać opcję -DnewVersion = {versionToBeUpdated}, aby uniknąć wprowadzania jej interaktywnie.
— Mukesh,

1
Myślę, że to najlepsza odpowiedź, automatyzuje zmiany wersji bez przerywania podprojektów (do których nie można by się odwoływać bez nadrzędnego pom).
— Tarek

Tak! Oto odpowiedź. 🙌
— aaiezza

Jeśli wersja potomna i nadrzędna pom są początkowo różne, najpierw zaktualizuj je, aby pasowały, w przeciwnym razie mvn versions:update-child-modules wszystkie wersje pom modułu podrzędnego zostaną pominięte.
— Gautam Tadigoppula

75

Od wersji Maven 3.5.0 możesz do tego użyć ${revision}symbolu zastępczego. Użycie jest udokumentowane tutaj: Maven CI Friendly Versions .

Krótko mówiąc, nadrzędny pom wygląda tak (cytowany z dokumentacji Apache):

<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>

a dziecko pom tak

<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>

Również trzeba użyć Spłaszcz Maven Plugin do generowania dokumentów pom z dedykowanym numerem wersji dołączonego do wdrożenia. Poradnik jest udokumentowany w powiązanej dokumentacji.

Również @khmarbaise napisał miły post blob o tej funkcji: Pliki Maven: POM Bez wersji w nim?


Skonfigurowałem swój projekt tak, jak opisałeś, ale bez „wtyczki Flatten Maven” i wydaje się, że działa zgodnie z oczekiwaniami, czy to możliwe? Mam również błąd w maven 3.2.1, ale maven 3.3.9+ wydaje się działać dobrze.
— Max

@Max To zależy od tego, co definiujesz jako „praca zgodnie z oczekiwaniami”. Wydaje mi się, że kompilacja przejdzie, ale instalacja / wdrożenie do repozytorium prawdopodobnie nie będzie dobrym pomysłem, ponieważ w podrzędnym pom nie ma numeru wersji, a jedynie symbol zastępczy (patrz dokumentacja )
— FrVaBe

Korzystam z <version> $ {rewizja} </version> w pom pom z nadrzędną właściwością domyślną (<properties> <wersja> 0.1-default </version> </properties>. Pomorskie dzieci również używają <version> $ {rewizja} < / version> Używam „mvn clean install -Drevision = 0.1. $ {bamboo.buildNumber}”. Kiedy skanuję logi wdrożenia wszystko jest ustawione na 0.1.820 i 0.1-default nie jest nawet w logach (820 to buildNumber). Kiedy skanuję wynikowy słoik, widzę w manifeście „Implementation-Version: 0.1.820”, a także „version = 0.1.820” w pliku pom.properties. Sam plik pom ma <wersja> $ {wersja} </version>. Więc myślę, że jest w porządku?
— Max

1
@Max Spróbuj rozwiązać słoik, w którym wersja znajduje się ${revision} w pom (w repozytorium maven), jako zależność w innym projekcie. Nie sądzę, że to zadziała.
— FrVaBe,

Jest to przydatne, z wyjątkiem sytuacji, gdy robię wydanie. To zastępuje ${revision}w tagu wersji nową wersją
— Mike D

21

Jak wspomniał Yanflea, istnieje sposób na obejście tego.

W Maven 3.5.0 możesz użyć następującego sposobu przeniesienia wersji z projektu nadrzędnego:

Nadrzędny plik 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>

Moduł 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>

Możesz zmienić myversionna dowolne, co nie jest zastrzeżoną własnością.


3
Odnosząc się do modułu z innego projektu, Maven nie rozpoznaje właściwości. Czy to normalne?
— LeoLozes

Uważam, że to pytanie może być warte własnego wpisu i nie może być w komentarzu takim jak ten. Nie widząc twojego kodu, mogę tylko zgadywać.
— eFox

@LeoLozes Czy rozwiązałeś problem (moduł referencyjny z innego projektu)?
— Morteza Malvandi

@MortezaMalvandi tak! Moja odpowiedź jest na dole :)
— LeoLozes 30.01.2019

2
Maven 3.6.0 ostrzega przed tą konfiguracją: „Zaleca się naprawienie tych problemów, ponieważ zagrażają one stabilności twojej wersji”. „Z tego powodu przyszłe wersje Maven mogą już nie obsługiwać tworzenia takich źle sformułowanych projektów”.
— d2k2

17

Możesz również użyć:

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

zaktualizować numery wersji w POM.


10

Odpowiedź eFox działała dla jednego projektu, ale nie wtedy, gdy odwoływałem się do modułu z innego (plik pom.xml nadal był przechowywany w mojej .m2właściwości zamiast wersji).

Działa jednak, jeśli połączysz go z flatten-maven-plugin, ponieważ generuje poms z poprawną wersją, a nie właściwością.

Jedyną opcją, którą zmieniłem w definicji wtyczki outputDirectory, jest domyślnie pusta, ale wolę ją mieć target, która jest ustawiona w mojej .gitignorekonfiguracji:

<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>

Konfiguracja wtyczki znajduje się w nadrzędnym pliku pom.xml



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>

Masz na myśli, że chcesz usunąć wersję z bloku nadrzędnego pom pom B, myślę, że nie możesz tego zrobić, groupId, artefactId i wersja określiły współrzędne pom nadrzędnego, co możesz pominąć, to wersja podrzędna.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.