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?

Shengjie
źródło
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.

Michał Kalinowski
źródło
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ę.

Yanflea
źródło
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ć.

pai
źródło
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?

FrVaBe
źródło
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ą.

eFox
źródło
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.

Jerry Jin
źródło
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

LeoLozes
źródło
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.

Yu Chai
źródło