Warisan versi proyek Maven - apakah saya harus menentukan versi induknya?

189

Saya punya dua proyek: Proyek induk: A, Sub proyek: B

A / pom.xml:

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

Dan di B / pom.xml, saya punya:

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

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

Saya ingin B mewarisi versi dari orangtua, jadi satu-satunya tempat dalam kasus saya yang perlu saya taruh 0.1-SNAPSHOTadalah A/pom.xml. Tetapi jika saya menghapus <version>0.1-SNAPSHOT</version>dari di B/pom.xmlbawah bagian induk, maven mengeluh tentang versi yang hilang untuk induk.

Apakah ada cara saya bisa menggunakan ${project.version}atau sesuatu seperti ini untuk menghindari 01.-SNAPSHOTdi kedua pom?

Shengjie
sumber
4
Anda harus menunggu Maven 3.1 untuk itu, saya khawatir.
Persepsi
1
Tautan di atas telah pindah. Status terakhir adalah "Closed / Won't Fix" issues.apache.org/jira/browse/MNG-624
jocull

Jawaban:

86

EDIT: Sejak Maven 3.5.0 ada solusi yang bagus untuk menggunakan ${revision}placeholder ini. Lihat jawaban FrVaBe untuk detailnya. Untuk versi Maven sebelumnya lihat jawaban asli saya di bawah ini.


Tidak, tidak ada. Anda selalu harus menentukan versi orang tua. Untungnya, itu diwarisi sebagai versi modul apa yang diinginkan dalam kebanyakan kasus. Selain itu, deklarasi versi orang tua ini dibentur secara otomatis oleh Maven Release Plugin, jadi - pada kenyataannya - bukan masalah bahwa Anda memiliki versi di 2 tempat selama Anda menggunakan Maven Release Plugin untuk merilis atau hanya menabrak versi.

Perhatikan bahwa ada beberapa kasus ketika perilaku ini sebenarnya cukup OK dan memberikan lebih banyak fleksibilitas yang mungkin Anda butuhkan. Terkadang Anda ingin menggunakan beberapa versi orang tua sebelumnya untuk mewarisi, namun itu bukan kasus umum.

Michał Kalinowski
sumber
3
Sekarang Anda dapat menggunakan ${revision}placeholder untuk ini. Lihat jawaban saya ;-)
FrVaBe
2
Ini sudah ketinggalan zaman - periksa @ FrVaBe di sini: stackoverflow.com/a/51969067/514483
robd
@FrVaBe bagaimana jika kita memiliki orang tua bersarang dengan versi yang berbeda? Kami tidak dapat menggunakan satu properti $ {revisi} di sana, itu tidak cukup.
Halil
@halil Pertanyaannya adalah tentang mewarisi versi dari orangtua dengan tujuan memiliki versi yang sama dalam dua artefak. Jika Anda memiliki orang tua yang berbeda dengan versi yang berbeda (dalam hierarki warisan) Anda mungkin tidak akan menjadikan mereka semua versi yang sama. Karena itu saya tidak sepenuhnya memahami komentar tersebut.
FrVaBe
86

Maven tidak dirancang untuk bekerja seperti itu, tetapi ada solusi untuk mencapai tujuan ini (mungkin dengan efek samping, Anda harus mencoba). Kuncinya adalah memberi tahu proyek anak untuk menemukan induknya melalui jalur relatifnya daripada koordinat maven murninya, dan di samping mengeksternalisasi nomor versi di properti:

Pom orang tua

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

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

Saya menggunakan trik itu untuk sementara waktu untuk salah satu proyek saya, tanpa masalah khusus, kecuali fakta bahwa maven mencatat banyak peringatan di awal pembuatan, yang tidak terlalu elegan.

EDIT

Tampaknya pakar 3.0.4 tidak mengizinkan konfigurasi seperti itu lagi.

Yanflea
sumber
2
ya, saya takut pakar tidak dirancang untuk bekerja seperti itu, lebih baik tetap dengan menempatkan versi di sub pom.xml. Plugin rilis pakar juga tidak terlalu peduli dengan versi yang ada.
Shengjie
7
untuk 3.0.5 berfungsi ok. Anda harus meletakkan <properties> di bagian paling atas sekalipun.
ses
7
Ia bekerja di 3.2.3. Lokasi <properties> tidak masalah. Anda akan mendapatkan peringatan:'version' contains an expression but should be a constant.
kapex
4
Tolong, berhati-hatilah dengan ini. Ini tidak berfungsi ketika proyek Anda dirujuk oleh proyek lain. Properti tidak akan diselesaikan dan akan diperlakukan secara harfiah (yaitu $ {my.version}). Ini akan menyebabkan kegagalan ketika menyelesaikan dependensi.
spekdrum
2
Saya juga telah menggunakan ini cukup lama sekarang dan berfungsi dengan baik (saat ini dengan pakar 3.3.9) untuk proyek multi-modul tunggal. Namun begitu proyek Anda menjadi ketergantungan proyek lain hal-hal menjadi rumit. Saya sangat menyarankan mengadopsi saran yang diusulkan oleh @pay di bawah ini.
cerdik
81

Cara termudah untuk memperbarui versi IMO:

$ mvn versions:set -DgenerateBackupPoms=false

(lakukan itu di folder pom root / parent Anda).

POM Anda diuraikan dan Anda diminta untuk menentukan versi mana.

pai
sumber
17
Anda juga dapat menambahkan -DnewVersion = {versionToBeUpdated} untuk menghindari memasukkannya secara interaktif.
Mukesh
1
Saya pikir ini adalah jawaban terbaik, itu mengotomatiskan perubahan versi tanpa melanggar subproyek (yang Anda tidak akan dapat referensi tanpa pom induk).
Tarek
Ya! Ini jawabannya. 🙌
aaiezza
Jika versi anak dan orang tua pom pada awalnya berbeda, perbarui dulu untuk mencocokkan, mvn versions:update-child-modules jika tidak semua versi anak pom modul akan dilewati.
Gautam Tadigoppula
75

Karena Maven 3.5.0 Anda dapat menggunakan ${revision}placeholder untuk itu. Penggunaannya didokumentasikan di sini: Versi Ramah Maven CI .

Singkatnya, parent pom terlihat seperti ini (dikutip dari dokumentasi 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>

dan anak pom menyukai ini

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

Anda juga harus menggunakan Flatten Maven Plugin untuk menghasilkan dokumen pom dengan nomor versi khusus yang disertakan untuk penerapan. HowTo didokumentasikan dalam dokumentasi tertaut.

@Khmarbaise juga menulis posting yang bagus tentang fitur ini: Maven: File POM Tanpa Versi di dalamnya?

FrVaBe
sumber
Saya mengkonfigurasi proyek saya seperti yang Anda gambarkan, tetapi tanpa "Flatten Maven Plugin" dan sepertinya berfungsi seperti yang diharapkan, apakah ini mungkin? Saya juga mendapat kesalahan dengan maven 3.2.1, tetapi maven 3.3.9+ sepertinya berfungsi dengan baik.
Maks
@ Max Ini tergantung apa yang Anda definisikan sebagai "bekerja seperti yang diharapkan". Saya kira build akan lulus tetapi instal / deploy ke repositori mungkin bukan ide yang baik karena tidak ada nomor versi di pom anak tetapi hanya placeholder (lihat dokumentasi )
FrVaBe
Saya menggunakan <version> $ {revisi} </version> di pom induk dengan properti default (<properties> <version> 0,1-default </version> </properties>. Anak pom juga menggunakan <version> $ {revisi} < / versi>. Saya menggunakan "mvn clean install -Drevision = 0,1. $ {bamboo.buildNumber}". Ketika saya memindai log penyebaran semuanya diatur ke 0.1.820 dan 0.1-default bahkan tidak ada dalam log (820) adalah buildNumber) .Ketika saya memindai tabung yang dihasilkan saya melihat "Implementasi-Versi: 0.1.820" dalam manifes, dan juga "versi = 0.1.820" dalam file pom.properties. File pom itu sendiri memiliki <version> $ {revisi} </version>. Jadi saya pikir tidak apa-apa?
Maks
1
@ Max Cobalah untuk menyelesaikan stoples di mana versi ${revision} di pom (dalam repositori maven) sebagai ketergantungan dalam proyek lain. Saya tidak berpikir ini akan berhasil.
FrVaBe
Ini berguna kecuali ketika saya melakukan rilis. Itu menggantikan ${revision}dalam tag versi dengan versi baru
Mike D
21

Seperti yang disebutkan Yanflea, ada cara untuk menyiasatinya.

Di Maven 3.5.0 Anda dapat menggunakan cara berikut untuk mentransfer versi dari proyek induk:

POM.xml induk

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

Anda bebas mengubah myversionke apa pun yang Anda inginkan yang bukan properti yang dipesan.

eFox
sumber
3
Saat mereferensikan modul dari proyek lain, Maven tidak menyelesaikan properti. Apakah itu normal?
LeoLozes
Saya percaya pertanyaan itu mungkin layak masuk sendiri dan tidak dalam komentar seperti ini. Tanpa melihat kode Anda, saya hanya bisa menebak.
eFox
@LeoLozes Apakah Anda memecahkan masalah Anda (modul referensi dari proyek lain)?
Morteza Malvandi
@MortezaMalvandi ya! Jawaban saya ada di bagian bawah :)
LeoLozes
2
Maven 3.6.0 memberikan peringatan untuk konfigurasi ini: "Sangat disarankan untuk memperbaiki masalah ini karena mereka mengancam stabilitas bangunan Anda." "Karena alasan ini, versi Maven masa depan mungkin tidak lagi mendukung pembangunan proyek cacat seperti itu."
d2k2
18

Anda juga bisa menggunakan:

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

untuk memperbarui nomor versi di POM Anda.

Jerry Jin
sumber
10

Jawaban eFox bekerja untuk satu proyek, tetapi tidak ketika saya mereferensikan modul dari yang lain (pom.xml masih disimpan di .m2properti saya dengan alih-alih versi).

Namun, ini berfungsi jika Anda menggabungkannya dengan flatten-maven-plugin, karena menghasilkan pom dengan versi yang benar, bukan properti.

Satu-satunya opsi yang saya ubah dalam definisi plug-in adalah outputDirectory, itu kosong secara default, tapi saya lebih suka memilikinya target, yang diatur dalam .gitignorekonfigurasi saya :

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

Konfigurasi plug-in berlaku di pom.xml induk

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

Maksud Anda, Anda ingin menghapus versi dari blok induk pom B, saya pikir Anda tidak dapat melakukannya, groupId, artifactId, dan versi yang ditentukan koordinat pom induk, yang dapat Anda hilangkan adalah versi anak.

Yu Chai
sumber