Спадщина версії проекту Maven - чи потрібно вказати батьківську версію?


189

У мене два проекти: Батьківський проект: A, Підпроект: B

A / pom.xml:

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

А в B / pom.xml у мене є:

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

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

Я хочу B успадковувати версію від батьків, так що єдине місце в моєму випадку мені потрібно поставити 0.1-SNAPSHOTце A/pom.xml. Але якщо я видалю <version>0.1-SNAPSHOT</version>з- B/pom.xmlпід батьківського розділу, Maven скаржиться на відсутність версії для батьків.

Чи є спосіб, який я можу просто використати ${project.version}чи щось подібне, щоб уникнути появи 01.-SNAPSHOTв обох дружин?


4
Боюся, вам доведеться чекати Maven 3.1.
Сприйняття



1
Посилання вище було переміщено. Остаточний статус був "Закрито / Не виправлять" проблеми.apache.org
jira

Відповіді:


86

EDIT: Оскільки Maven 3.5.0 є приємне рішення для цього за допомогою ${revision}заповнювача. Детальніше дивіться у відповіді FrVaBe . Для попередніх версій Maven дивіться мою оригінальну відповідь нижче.


Ні, немає. Ви завжди повинні вказати версію батьків. На щастя, він успадковується як версія модуля, що бажано в більшості випадків. Більше того, декларація версії цього батька автоматично стикається плагіном Maven Release, тому - насправді - це не проблема, якщо у вас є версія у двох місцях, якщо ви використовуєте Maven Release Plugin для випуску або просто перешкоджання версій.

Зауважте, що є деякі випадки, коли така поведінка насправді досить нормальна і надає вам більшої гнучкості. Іноді ви хочете використовувати деякі з попередніх батьківських версій для успадкування, однак це не основний випадок.


3
Сьогодні ви можете використовувати ${revision}для цього заповнювач. Дивіться мою відповідь ;-)
FrVaBe

2
Це вже застаріли - перевірка @ відповідь FrVaBe тут: stackoverflow.com/a/51969067/514483
robd

@FrVaBe Що робити, якщо ми вклали батьків із різними версіями? Ми не можемо використати там один ресурс $ {revision}, цього недостатньо.
Халіл

@halil Питання полягає у успадкуванні версії від батьків з метою мати ту саму версію у двох артефактах. Якщо у вас різні батьки з різними версіями (в ієрархії спадкування), ви, ймовірно, не зробите їх усіма однаковими версіями. Тому я не повністю розумію коментар.
FrVaBe

86

Maven не призначений для роботи таким чином, але для досягнення цієї мети існує рішення (можливо, з побічними ефектами вам доведеться спробувати). Хитрість полягає в тому, щоб сказати дочірньому проекту знайти свого батька через його відносний шлях, а не через чисті координати Maven, а також доповнити номер версії у властивості:

Батьківська пом

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

Дитяча пом

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

Я використовував цей трюк деякий час для свого проекту, не маючи особливих проблем, за винятком того, що Maven записує багато попереджень на початку складання, що не дуже елегантно.

EDIT

Здається, maven 3.0.4 вже не дозволяє такої конфігурації.


2
так, боюся, Maven не призначений для роботи таким чином, краще просто дотримуйтесь розміщення версій у sub pom.xml. плагін випуску maven у будь-якому разі насправді не хвилює версії, які існують.
Shengjie

7
для 3.0.5 працює добре. ви повинні поставити <властивості> на самому верху.
ses

7
Це працює в 3.2.3. Розташування <властивостей> значення не має. Однак ви отримаєте попередження:'version' contains an expression but should be a constant.
kapex

4
Будь ласка, будьте обережні з цим. Це не працює, коли на ваш проект посилається інший проект. Властивість не буде вирішено, і вона буде оброблена буквально (тобто $ {my.version}). Це призведе до невдачі при вирішенні залежностей.
spekdrum

2
Я також використовую це вже досить давно, і він працює чудово (зараз з Maven 3.3.9) для одного мультимодульного проекту. Однак, як тільки ваш проект стає залежним від іншого проекту, речі стають реально складними. Я дійсно пропоную прийняти пропозицію, запропоновану @pay нижче.
геніальний

81

Найпростіший спосіб оновити версії IMO:

$ mvn versions:set -DgenerateBackupPoms=false

(зробіть це у своїй кореневій / батьківській папці pom).

Ваші POM-файли розбираються, і ви запитуєте, яку версію встановити.


17
Ви також можете додати -DnewVersion = {versionToBeUpdate}, щоб уникнути інтерактивного введення.
Мукеш

1
Я думаю, що це найкраща відповідь, вона автоматизує зміни версій, не порушуючи підпроекти (на які ви не змогли б посилатися без батьківського пам’яті).
Тарек

Так! Це відповідь. 🙌
aaiezza

Якщо дочірня та батьківська версії pom спочатку відрізняються, спочатку оновіть їх на відповідність, mvn versions:update-child-modules інакше вся помпонна версія модуля пом буде пропущена.
Гаутам Тадігоппула

75

З Maven 3.5.0 ви можете використовувати для цього ${revision}заповнювач. Використання задокументовано тут: Maven CI Friendly Versions .

Коротше кажучи, батьківський пом виглядає так (цитується з документації 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>

і дитина пом. так

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

Крім того, ви повинні використовувати плагін Flatten Maven для генерування пам’ятних документів із спеціальним номером версії, включеною для розгортання. HowTo зафіксовано у зв'язаній документації.

Також @khmarbaise написав приємну публікацію про цю функцію: Maven: Файли POM без версії в ній?


Я налаштував свій проект так, як ви описали, але без "Flatten Maven Plugin" і, здається, працює так, як очікувалося, чи можливо це? Також я отримав помилку з Maven 3.2.1, але, схоже, maven 3.3.9+ працює нормально.
Макс

@Max Це залежить від того, що ви визначаєте як "працюйте як очікувалося". Я думаю, що збірка пройде, але встановлення / розгортання у сховищі, ймовірно, не буде гарною ідеєю, оскільки в дочірньому
пам’яті

Я використовую <version> $ {revision} </version> в батьківському пом з властивістю за замовчуванням (<properties> <version> 0,1-за замовчуванням </version> </properties>. Дочірні батьки також використовують <version> $ {revision} < / версія>. Я використовую "mvn clean install -Drevision = 0.1. $ {bamboo.buildNumber}". Коли я сканую журнали розгортання, все встановлюється на 0,1.820, а 0,1 - за замовчуванням навіть не є в журналах (820 Коли я сканую отриману банку, я бачу "Implementation-Version: 0.1.820" у маніфесті, а також "version = 0.1.820" у файлі pom.properties. Сам файл Pom <version> $ {revision} </version> .Так я вважаю, що це добре?
Макс

1
@Max Спробуйте вирішити банку, де версія знаходиться ${revision} в пом (у сховищі Maven) як залежність в іншому проекті. Я не думаю, що це спрацює.
FrVaBe

Це корисно за винятком випадків, коли я роблю реліз. Це замінює ${revision}тег версії новою версією
Mike D

21

Як згадував Янфлеа, є спосіб подолати це.

У Maven 3.5.0 ви можете використовувати наступний спосіб перенесення версії від батьківського проекту:

Батьківський 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>

Модуль 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>

Ви можете змінювати myversionвсе, що завгодно, що не є зарезервованою власністю.


3
Посилаючись на модуль з іншого проекту, Maven не вирішує властивість. Це нормально?
LeoLozes

Я вважаю, що це питання може бути гідним його власного вступу та не мати такого коментаря. Не бачачи вашого коду, я можу лише здогадуватися.
eFox

@LeoLozes Ви вирішили свою проблему (модуль відбиття від іншого проекту)?
Мортеза Мальванді

@MortezaMalvandi так! Моя відповідь внизу :)
LeoLozes

2
Maven 3.6.0 подає попередження для цієї конфігурації: "Настійно рекомендується виправити ці проблеми, оскільки вони загрожують стабільності вашої збірки." "З цієї причини майбутні версії Maven більше не можуть підтримувати створення таких неправильних проектів."
d2k2

17

Ви також можете використовувати:

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

оновити номери версій у ваших POM.


10

Відповідь eFox працювала для одного проекту, але не тоді, коли я посилався на модуль з іншого (pom.xml все ще зберігався в моєму .m2властивості замість версії).

Однак він працює, якщо поєднувати його з flatten-maven-plugin, оскільки він генерує poms з правильною версією, а не властивістю.

Єдиний варіант, який я змінив у визначенні плагіна - це outputDirectory, він за замовчуванням порожній, але я вважаю за краще його мати target, який встановлено в моїй .gitignoreконфігурації:

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

Конфігурація плагіна входить у батьківський 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>

Ви маєте на увазі, що хочете видалити версію з батьківського блоку пам’яті B, я думаю, ви не можете цього зробити, groupId, artifactId і версія вказали координату пом. Батьків, що ви можете опустити - це дочірня версія.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.