Maven induk pom vs modul pom

284

Tampaknya ada beberapa cara untuk menyusun pom induk dalam membangun multi proyek dan saya bertanya-tanya apakah ada yang punya pemikiran tentang apa kelebihan / kekurangan dalam setiap cara.

Metode paling sederhana untuk memiliki pom induk adalah dengan meletakkannya di root proyek yaitu

myproject/
  myproject-core/
  myproject-api/
  myproject-app/
  pom.xml

di mana pom.xml adalah proyek induk sekaligus menjelaskan modul -core -api dan -app

Metode selanjutnya adalah memisahkan induk ke dalam subdirektori sendiri seperti pada

myproject/
  mypoject-parent/
    pom.xml
  myproject-core/
  myproject-api/
  myproject-app/

Di mana pom induk masih berisi modul tetapi mereka relatif, misalnya ../myproject-core

Akhirnya, ada opsi di mana definisi modul dan induk dipisahkan seperti pada

myproject/
  mypoject-parent/
    pom.xml
  myproject-core/
  myproject-api/
  myproject-app/
  pom.xml

Di mana pom induk berisi konfigurasi "bersama" (dependensiManajemen, properti, dll.) Dan myproject / pom.xml berisi daftar modul.

Niatnya adalah untuk scalable untuk membangun skala besar sehingga harus scalable untuk sejumlah besar proyek dan artefak.

Beberapa pertanyaan bonus:

  • Di mana tempat terbaik untuk mendefinisikan berbagai konfigurasi bersama seperti dalam kontrol sumber, direktori penempatan, plugin umum dll. (Saya mengasumsikan orang tua tetapi saya sering digigit oleh ini dan mereka telah berakhir di setiap proyek daripada yang umum).
  • Bagaimana plugin maven-release, hudson, dan nexus berurusan dengan bagaimana Anda mengatur multi-proyek Anda (mungkin pertanyaan raksasa, lebih dari itu jika ada yang terperangkap ketika bagaimana membangun multi-proyek telah diatur)?

Sunting: Masing-masing sub proyek memiliki pom.xml mereka sendiri, saya telah meninggalkannya untuk tetap singkat.

Jamie McCrindle
sumber
Apakah masing-masing modul memiliki pom sendiri? Proyek saya memiliki pom induk, tetapi masing-masing modul memiliki pom juga. (mungkin cara keempat untuk apa yang Anda gambarkan)
harschware
Ah, ya, saya akan mengedit dan memperbarui. Setiap submodula memiliki pom sendiri juga.
Jamie McCrindle
3
Sama seperti pembaruan, saya dapat melihat keuntungan dari opsi kedua adalah bahwa lebih mudah untuk mengelola di Eclipse di mana root pom.xml dalam contoh pertama dan ketiga akan sulit untuk dimasukkan jika sub modul adalah proyek terpisah di Eclipse.
Jamie McCrindle

Jawaban:

166

Menurut pendapat saya, untuk menjawab pertanyaan ini, Anda perlu berpikir dalam hal siklus hidup proyek dan kontrol versi. Dengan kata lain, apakah pom induk memiliki siklus hidup sendiri yaitu dapatkah itu dirilis secara terpisah dari modul lain atau tidak?

Jika jawabannya adalah ya (dan ini adalah kasus sebagian besar proyek yang telah disebutkan dalam pertanyaan atau dalam komentar), maka orang tua pom membutuhkan modulnya sendiri dari VCS dan dari sudut pandang Maven dan Anda akan berakhir dengan sesuatu seperti ini di tingkat VCS:

root
|-- parent-pom
|   |-- branches
|   |-- tags
|   `-- trunk
|       `-- pom.xml
`-- projectA
    |-- branches
    |-- tags
    `-- trunk
        |-- module1
        |   `-- pom.xml
        |-- moduleN
        |   `-- pom.xml
        `-- pom.xml

Ini membuat checkout sedikit menyakitkan dan cara umum untuk menghadapinya adalah dengan menggunakannya svn:externals. Misalnya, tambahkan trunksdirektori:

root
|-- parent-pom
|   |-- branches
|   |-- tags
|   `-- trunk
|       `-- pom.xml
|-- projectA
|   |-- branches
|   |-- tags
|   `-- trunk
|       |-- module1
|       |   `-- pom.xml
|       |-- moduleN
|       |   `-- pom.xml
|       `-- pom.xml
`-- trunks

Dengan definisi eksternal berikut:

parent-pom http://host/svn/parent-pom/trunk
projectA http://host/svn/projectA/trunk

Proses checkout trunksakan menghasilkan struktur lokal berikut (pola # 2):

root/
  parent-pom/
    pom.xml
  projectA/

Secara opsional, Anda bahkan dapat menambahkan pom.xmldalam trunksdirektori:

root
|-- parent-pom
|   |-- branches
|   |-- tags
|   `-- trunk
|       `-- pom.xml
|-- projectA
|   |-- branches
|   |-- tags
|   `-- trunk
|       |-- module1
|       |   `-- pom.xml
|       |-- moduleN
|       |   `-- pom.xml
|       `-- pom.xml
`-- trunks
    `-- pom.xml

Ini pom.xmladalah semacam pom "palsu": tidak pernah dirilis, tidak mengandung versi nyata karena file ini tidak pernah dirilis, hanya berisi daftar modul. Dengan file ini, checkout akan menghasilkan struktur ini (pola # 3):

root/
  parent-pom/
    pom.xml
  projectA/
  pom.xml

"Retasan" ini memungkinkan untuk meluncurkan bangunan reaktor dari root setelah checkout dan membuat segalanya menjadi lebih praktis. Sebenarnya, ini adalah bagaimana saya ingin mensetup proyek maven dan repositori VCS untuk build besar : itu hanya berfungsi, ini berskala dengan baik, memberikan semua fleksibilitas yang mungkin Anda butuhkan.

Jika jawabannya tidak (kembali ke pertanyaan awal), maka saya pikir Anda dapat hidup dengan pola # 1 (melakukan hal paling sederhana yang mungkin bisa berhasil).

Sekarang, tentang pertanyaan bonus:

  • Di mana tempat terbaik untuk mendefinisikan berbagai konfigurasi bersama seperti dalam kontrol sumber, direktori penempatan, plugin umum dll. (Saya mengasumsikan orang tua tetapi saya sering digigit oleh ini dan mereka telah berakhir di setiap proyek daripada yang umum).

Jujur, saya tidak tahu bagaimana tidak memberikan jawaban umum di sini (seperti "gunakan tingkat yang menurut Anda masuk akal untuk saling menguntungkan"). Lagi pula, pom anak selalu dapat mengesampingkan pengaturan bawaan.

  • Bagaimana plugin maven-release, hudson, dan nexus berurusan dengan bagaimana Anda mengatur multi-proyek Anda (mungkin pertanyaan raksasa, lebih dari itu jika ada yang terperangkap ketika bagaimana membangun multi-proyek telah diatur)?

Pengaturan yang saya gunakan berfungsi dengan baik, tidak ada yang khusus untuk disebutkan.

Sebenarnya, saya bertanya-tanya bagaimana penawaran maven-release-plugin dengan pola # 1 (terutama dengan <parent>bagian karena Anda tidak dapat memiliki dependensi SNAPSHOT pada waktu rilis). Ini terdengar seperti masalah ayam atau telur, tetapi saya tidak ingat apakah itu berhasil dan terlalu malas untuk mengujinya.

Thivent Pascal
sumber
Itu sangat bagus karena saya dapat melihat bagaimana skala. Svn: eksternal menjawab kekhawatiran saya tentang hal itu rumit.
Jamie McCrindle
@ jamie Senang Anda menemukannya bermanfaat.
Pascal Thivent
1
Bisakah Anda menguraikan cara-cara untuk membuat "hack" bekerja? Saya sudah mendapatkan proyek trunk dan mengantisipasi bahwa Anda menargetkan opsi -pl dengan "peluncuran build reaktor" tetapi ini menjadi masalah ketika melakukan rilis pada struktur karena opsi ini tidak lulus dari build di level root juga. dapatkah saya menempatkannya di opsi <argumen /> dari rilis-Plugin. Oleh karena itu rilis: melakukan failes karena mencoba untuk bekerja pada pom tingkat akar ...
Jan
The svn: hack eksternal adalah hack svn paling berguna yang telah saya lihat dalam waktu yang lama. Sangat membantu dengan proyek yang memiliki percabangan per proyek dalam repositori yang sama.
omerkudat
1
Hai Pascal, Bagaimana Anda menangani versi # jika proyek yang disebutkan di bagian modul, tidak menggunakan parent-pom sebagai <pihak> tetapi orang lain-proyek-parent-pom? Versi apa yang akan kita dapatkan untuk artefak dari proyek-proyek semacam itu (# versi artefak di bagian <pihak> proyek-proyek ATAU # versi Proyek yang mencantumkan proyek-proyek ini sebagai modul)? stackoverflow.com/questions/25918593/...
AKS
34

Dari pengalaman saya dan praktik terbaik Maven ada dua jenis "induk pom"

  • pom induk "perusahaan" - pom ini berisi informasi dan konfigurasi khusus perusahaan Anda yang mewarisi setiap pom dan tidak perlu disalin. Informasi ini adalah:

    • repositori
    • bagian manajemen distribusi
    • konfigurasi plugin umum (seperti maven-compiler-plugin source dan versi target)
    • organisasi, pengembang, dll

    Mempersiapkan pom induk ini perlu dilakukan dengan hati-hati, karena semua pom perusahaan Anda akan mewarisinya, sehingga pom ini harus matang dan stabil (melepaskan versi pom induk tidak akan mempengaruhi untuk melepaskan semua proyek perusahaan Anda!)

  • pom jenis induk kedua adalah induk multimodule. Saya lebih suka solusi pertama Anda - ini adalah konvensi standar untuk proyek multi-modul, sangat sering mewakili struktur kode VCS

Niatnya adalah untuk scalable untuk membangun skala besar sehingga harus scalable untuk sejumlah besar proyek dan artefak.

Mutliprojects memiliki struktur pohon - jadi Anda tidak diturunkan ke satu tingkat pom induk. Cobalah untuk menemukan struture proyek yang sesuai dengan kebutuhan Anda - contoh klasiknya adalah bagaimana mendisibusikan proyek-proyek mutimodule

distibution/
documentation/
myproject/
  myproject-core/
  myproject-api/
  myproject-app/
  pom.xml
pom.xml

Beberapa pertanyaan bonus:

  • Di mana tempat terbaik untuk mendefinisikan berbagai konfigurasi bersama seperti dalam kontrol sumber, direktori penempatan, plugin umum dll. (Saya mengasumsikan orang tua tetapi saya sering digigit oleh ini dan mereka telah berakhir di setiap proyek daripada yang umum).

Konfigurasi ini harus dengan bijak dipecah menjadi pom induk "perusahaan" dan pom induk proyek. Hal-hal yang berkaitan dengan semua yang Anda proyeksikan pergi ke induk "perusahaan" dan ini terkait dengan proyek saat ini masuk ke proyek orang tua.

  • Bagaimana plugin maven-release, hudson, dan nexus berurusan dengan bagaimana Anda mengatur multi-proyek Anda (mungkin pertanyaan raksasa, lebih dari itu jika ada yang terperangkap ketika bagaimana membangun multi-proyek telah diatur)?

Perusahaan induk pom harus dibebaskan terlebih dahulu. Untuk multi proyek aturan standar berlaku. Server CI perlu mengetahui semua untuk membangun proyek dengan benar.

cetnar
sumber
1
Sehingga ada dua jenis proyek induk / pom. Satu tanpa pernyataan <modules>. Ini adalah yang digunakan untuk Warisan. Dan proyek induk dengan deklarasi <multimodule>. Ini adalah salah satu yang tidak diwariskan oleh submodul, itu hanya untuk mengelola pembangunan proyek tahan. Apakah saya benar ?
lisak
22
  1. Induk independen adalah praktik terbaik untuk berbagi konfigurasi dan opsi di seluruh komponen yang tidak dipisahkan. Apache memiliki proyek induk pom untuk berbagi pemberitahuan hukum dan beberapa opsi pengemasan umum.

  2. Jika proyek tingkat atas Anda memiliki pekerjaan nyata di dalamnya, seperti menggabungkan javadoc atau mengemas rilis, maka Anda akan mengalami konflik antara pengaturan yang diperlukan untuk melakukan pekerjaan itu dan pengaturan yang ingin Anda bagikan melalui orang tua. Proyek khusus orangtua menghindari itu.

  3. Pola umum (mengabaikan # 1 untuk saat ini) adalah memiliki proyek-dengan-kode menggunakan proyek induk sebagai orangtua mereka, dan meminta mereka menggunakan tingkat atas sebagai induk. Ini memungkinkan hal-hal inti untuk dibagikan oleh semua orang, tetapi menghindari masalah yang dijelaskan dalam # 2.

  4. Plugin situs akan menjadi sangat bingung jika struktur induk tidak sama dengan struktur direktori. Jika Anda ingin membangun situs agregat, Anda perlu melakukan beberapa mengutak-atik ini.

  5. Apache CXF adalah contoh pola di # 2.

bmargulies
sumber
2
Saya sudah melihat ibilio dan banyak proyek tampaknya lebih suka pom induk "independen". Hibernate, ActiveMQ, Jetty, XStream dll. Yang menunjukkan itu adalah mekanisme defacto.
Jamie McCrindle
2
Kelemahan lain dari induk independen tampaknya adalah bahwa plugin rilis pakar ingin agar orang tua disematkan ke versi sebelum itu akan melakukan rilis. Mungkin tidak banyak masalah karena orang tua tidak boleh terlalu banyak berubah.
Jamie McCrindle
9

Ada satu tangkapan kecil dengan pendekatan ketiga. Karena POM agregat (myproject / pom.xml) biasanya tidak memiliki induk sama sekali, mereka tidak berbagi konfigurasi. Itu berarti semua POM agregat hanya akan memiliki repositori default.

Itu bukan masalah jika Anda hanya menggunakan plugin dari Central, namun, ini akan gagal jika Anda menjalankan plugin menggunakan plugin: format tujuan dari repositori internal Anda. Misalnya, Anda dapat foo-maven-pluginmenggunakan groupId untuk org.examplememberikan tujuan generate-foo. Jika Anda mencoba menjalankannya dari root proyek menggunakan perintah likemvn org.example:foo-maven-plugin:generate-foo , itu akan gagal dijalankan pada modul agregat (lihat catatan kompatibilitas ).

Beberapa solusi mungkin:

  1. Menyebarkan plugin ke Maven Central (tidak selalu memungkinkan).
  2. Tentukan bagian repositori di semua POM agregat Anda (jeda prinsip KERING ).
  3. Atur repositori internal ini dikonfigurasikan di settings.xml (baik dalam pengaturan lokal di ~ / .m2 / settings.xml atau dalam pengaturan global di /conf/settings.xml). Akan membuat build gagal tanpa pengaturan tersebut.xml (bisa OK untuk proyek in-house besar yang tidak pernah seharusnya dibangun di luar perusahaan).
  4. Gunakan induk dengan pengaturan repositori di POM agregat Anda (bisa jadi terlalu banyak POM induk?).
Ivan Dubrov
sumber