Memisahkan proyek besar untuk membuat proyek Maven multi-modul

23

Saya sedang mengerjakan aplikasi Spring-MVC di mana kami menggunakan Maven untuk manajemen ketergantungan. Karena proyek ini besar, kami berpikir untuk membagi proyek menjadi beberapa bagian. Saya memiliki beberapa keraguan, yang saya harap akan mendapat jawaban di sini.

Saat ini, kami sedang menyebarkan file WAR tunggal seperti ROOT.warpada tomcat Apache di server kami. Karena proyeknya besar, ada bagian di webapp seperti Notifikasi dan Email, layanan pihak ketiga, PUSH (Cometd), REST API's, dll. Saat ini semuanya dipukuli dan saling bergantung satu sama lain. Misalnya, Notificationobjek juga tergantung pada Personobjek, karena Pemberitahuan disesuaikan untuk pengguna.

Tujuan utama pemisahan proyek besar adalah untuk dapat bekerja pada modul individu, untuk perbaikan bug, menambahkan fitur, pengujian, dll. Dan ketika puas, maka hanya modul ini yang dapat diganti di server daripada seluruh aplikasi. Apakah ini mungkin?

Seperti yang sudah saya sebutkan sebelumnya, ada dependensi dan pemetaan antara objek. Bagaimana itu akan dikelola di berbagai sub-modul, atau hanya akan mengubah pernyataan impor untuk memasukkan proyek lain?

Seperti yang saya katakan, tujuannya adalah untuk bekerja pada modul individual dan dapat menggunakan mereka (lebih disukai panas). Saat ini, kami hanya memiliki satu file WAR sebagai ROOT.war. Akankah pemisahan membuat banyak file perang, yang kemudian disebut dengan URL domain-name.com/module_name/some_mapping?

Saat ini saya sedang memeriksa dokumentasinya, tetapi ini adalah tujuan utama yang ingin kami capai dengan multi modul yang disediakan oleh Maven dan tertarik untuk mengetahui apakah ini layak. Jika ada informasi lain yang diperlukan, harap beri tahu saya.

Saat ini saya menggunakan POM induk dari musim semi sebagai berikut:

<parent>
    <groupId>io.spring.platform</groupId>
    <artifactId>platform-bom</artifactId>
    <version>1.1.3.RELEASE</version>
    <relativePath />
</parent>
Kami adalah Borg
sumber
1
Saya serahkan pada orang lain untuk menjawab. Idenya sangat bagus. Anda bisa mulai dengan POM induk dengan dependencyManagement, dan toples untuk DAOs seperti Person. Perpustakaan yang sangat mendasar. Dan seterusnya. Tentu saja tidak ada ketergantungan siklik.
Joop Eggen

Jawaban:

20

Apa itu mungkin ?

Ya tentu. Dalam struktur masa lalu saya memiliki beberapa proyek seperti ini, di sini beberapa bit saya harap akan membantu Anda memulai.

Ada dua fitur utama Maven yang akan Anda gunakan untuk menenun semuanya:

Membagi dan menaklukkan

Anda perlu membagi proyek Anda menjadi beberapa proyek independen. Di sini dengan independen saya maksudkan bahwa semua referensi ke kode di luar proyek dilakukan melalui dependensi di Maven dan tidak secara langsung menggabungkan pohon sumber.

Bergantung pada kondisi pohon sumber Anda, ini bisa mewakili banyak pekerjaan. Yang mengatakan Anda tidak melakukannya untuk menyuruh Maven tetapi sebagai sarana untuk struktur dan membersihkan basis kode Anda. Anggap saja sebagai gudang alat Anda, jauh lebih mudah untuk menemukan hal-hal di sini:

Gudang alat bagus

dari sini:

Gudang alat yang tidak terlalu bagus

Maven sangat bergantung pada konvensi sehingga barang-barang Anda lebih terorganisir adalah lebih banyak Maven dapat membantu Anda. Yang mengatakan, Ini mungkin mengharuskan Anda untuk mengatur ulang agar lebih sesuai dengan konvensi itu sendiri dan jika saya harus memberikan satu saran di sini adalah bahwa JAUH lebih mudah untuk mengubah barang-barang Anda agar sesuai dengan konvensi Maven daripada mencoba dan mengkonfigurasi Maven untuk pahami konvensi Anda.

Jika proyek-proyek ini dapat digunakan di luar aplikasi utama mereka dapat hidup sebagai perpustakaan yang benar-benar independen dan termasuk dependensi. Mereka harus tinggal di repositori mereka sendiri (bukan di pohon sumber aplikasi) dan tidak boleh bergantung pada bagian mana pun dari aplikasi utama.

Bagian inti dari aplikasi Anda, begitu terpecah dalam proyek dapat disatukan sebagai modul. Biasanya Anda akan menempatkannya sebagai sub-folder dari folder sumber utama aplikasi Anda.

POM orang tua Anda untuk aplikasi Anda akan berisi deklarasi modul. Anda juga akan menempatkan semua dependensi umum untuk aplikasi Anda di sana serta mendeklarasikan sebagian besar plugin build dan konfigurasinya. Di sini saya juga merekomendasikan Anda menempatkan sekelompok properti untuk hal-hal seperti versi aplikasi yang dapat Anda gunakan kembali dalam modul. Jauh lebih mudah untuk dikelola ketika semuanya memiliki versi yang sama dan memiliki versi di satu tempat menjadikan ini hanya berfungsi.

Alat

Jika Anda adalah tim yang lebih besar dari 1, saya juga akan sangat menyarankan Anda menginstal repositori untuk dependensi Maven Anda. Lihatlah Artifactory , Nexus atau Archiva . Anda dapat mengonfigurasikan file POM untuk menginstalnya secara langsung sehingga sekali menjalankannya seharusnya tidak terlalu mahal tetapi akan menghemat waktu bagi tim Anda untuk menyelesaikan dependensi dengan toples yang tepat di tempat yang benar.

Pada masalah tooling, langkah logis berikutnya di sini adalah sistem integrasi berkelanjutan ( Jenkins , ada banyak lagi). Ini akan menangani membangun sumber menjalankan tes dan mendorong ke artifactory, dengan semua ini di tempat yang harus Anda lakukan adalah bekerja kode dan sisanya hanya berfungsi.

Karena Anda mengemas aplikasi Anda sebagai pakar perang dapat menangani pembangunan perang dan menempatkan semua dependensi di tempat yang tepat tanpa harus menggabungkan file jar atau pekerjaan serupa lainnya, jadi jangan khawatir di sana.

Contoh

Saya bisa bertahan lebih lama di sini tetapi tidak ada yang mengalahkan contoh yang baik. Lihatlah github untuk proyek-proyek dengan magnitudo yang serupa dan lihat bagaimana mereka membangun file pom dan hierarki folder mereka. Lihat lebih dari satu, beberapa akan cocok setup Anda lebih baik daripada yang lain, tidak ada yang benar-benar menjelma dalam kebenaran tetapi Anda harus menemukan cukup untuk bahan bakar pengalaman anda tentang cara untuk menyelesaikannya.

Ambil Jenkins misalnya:

Anda dapat melihat orang tua POM mereka cukup luas.

Mereka memang menggunakan modul seperti yang Anda lihat di bagian ini:

<modules>
    <module>core</module>
    <module>war</module>
    <module>test</module>
    <module>cli</module>
</modules>

Dan setiap modul sesuai dengan sub-folder dengan nama yang sama yang juga berisi POM. Anda dapat membuat sarang sebanyak yang Anda inginkan seperti ini, meskipun tetap dalam tingkat kewarasan;).

Mulai dari Kecil

Jika Anda belum pernah menggunakan Maven saya sarankan namun Anda tidak memulai dengan modul segera. Ambillah dengan lambat, mulailah dengan, katakanlah salah satu perpustakaan sederhana yang mungkin Anda miliki dan jadikan proyek maven. Kemudian buat aplikasi utama Anda menjadi proyek pakar sederhana. Setelah berhasil, mulailah menambahkan dependensi sederhana, lalu bagi modul pertama Anda dan seterusnya.

Maven adalah alat yang hebat tetapi juga bisa menjadi sangat sakit di leher terutama ketika segala sesuatu tidak berjalan sesuai keinginan Anda. Dimulai dengan seluruh omong kosong di perjalanan pertama Anda adalah penerima bencana (adalah untuk saya!).

Jika hal-hal agak aneh, Anda selalu dapat menggunakan mvn help:effective-pomperintah untuk melihat apa yang benar-benar dipahami Maven.

plugin

Dari komentar Anda, saya lebih mengerti apa yang ingin Anda capai. Dalam hal ini saya akan pergi untuk pendekatan plugin. Buat proyek yang memaparkan API titik ekstensi tempat Anda ingin mengisolasi pekerjaan. Kemudian Anda dapat menggunakan ini sebagai ketergantungan dalam proyek baru yang akan mengimplementasikannya. Di aplikasi utama Anda, tambahkan saja dependensi yang tepat untuk implementasi ini (tidak menggunakan modul pakar kali ini) dan Anda harus siap. Akhirnya proyek aplikasi utama hampir tidak membawa kode sumber apa pun yang dilakukan dalam proyek eksternal dan dimuat melalui dependensi.

Anda perlu menggunakan kembali seluruh aplikasi dengan pendekatan ini, terlepas dari apakah inti berubah atau tidak karena perang dibangun secara statis dari dependensi, mengubah salah satu dari aplikasi tersebut menyiratkan membangun kembali semuanya. Kedengarannya terburuk daripada yang sebenarnya, Akibatnya hanya perubahan baru yang benar-benar akan dibangun, sisanya pada dasarnya akan menjadi salinan dari toples sebelumnya. Tetapi karena semuanya ada di file perang itu perlu dibangun kembali, dan server harus dihentikan dan restart.

Jika Anda perlu melangkah lebih jauh, dapatkan sedikit lebih rumit, meskipun bukan tidak mungkin. Saya akan merekomendasikan Anda melihat ke OSGI, Apache Felix bisa membantu Anda memulai, meskipun ada implementasi lain juga. Ini akan memungkinkan Anda untuk mengambil tabung eksternal dan membuatnya menjadi plugin yang tepat. Anda akan mendapatkan lebih banyak kontrol pada siklus hidup runtime dari komponen yang membuka pintu untuk memuat ulang dan memperbarui secara dinamis. Namun itu akan membutuhkan perubahan besar pada inti Anda jadi sekali lagi, mungkin bukan titik awal yang baik. Namun begitu Anda memiliki proyek yang terpisah dengan baik dan mengisolasi semua bagian seperti yang Anda inginkan, itu bisa menjadi langkah alami berikutnya jika memulai dan menghentikan aplikasi pada pembaruan adalah masalah besar.

Perbedaan mendasar antara Modul dan dependensi adalah ini:

  • Modul akan hidup di pohon sumber yang sama dengan aplikasi utama, seperti sub-folder idealnya.
  • Ketergantungan dapat terjadi di mana saja.

Anda dapat menemukan Alkitab di sini .

Semoga ini bisa membantu, semoga berhasil.

Newtopian
sumber
Sebenarnya menggabungkan modul melalui pakar bukannya pohon sumber membersihkan banyak pertanyaan yang saya miliki. Bisakah Anda ceritakan tentang penyebaran proyek semacam itu. Salah satu alasan lain yang kami pertimbangkan adalah agar pengembang dapat mengerjakan modul yang diperlukan dan membuat perubahan secara realtime. Satu hal yang kami ingin hindari adalah menghentikan server aplikasi dan memulai lagi, selain untuk modul inti. Sebagai 2 modul saya dapat memikirkan akan berisi kode yang sering berubah. Kami menggunakan tomcat sebagai server aplikasi, loadbalanced oleh Apache. Terima kasih.
Kami adalah Borg
Modul Maven sering duduk di pohon sumber yang sama dengan aplikasi utama. Menggunakan modul pakar di luar pohon sumber sebenarnya lebih rumit daripada yang benar-benar layak. Jika Anda meng-host proyek di luar pohon sumber kemudian pergi untuk proyek independen normal dan gunakan dependensi normal.
Newtopian
Saya pikir kami akan pergi untuk menambahkan bagian dari proyek kami secara langsung sebagai dependensi Maven. Dengan cara ini, kita dapat langsung mengerjakan bagian-bagian proyek. Hanya satu pertanyaan yang saya miliki, jika kita menambahkan salah satu sub proyek sebagai ketergantungan pada POM.xml, katakan versi 2.0.0, dan kemudian dengan beberapa perubahan, kita dorong modul 2.0.1 ke sonatype, bagaimana kita bisa langsung beri tahu core-module untuk 2.0.1, hanya akan mengubah POM.xml di dalam ROOT.war dan menghapus direktori ROOT sudah cukup. Tujuan utama bukan untuk menghentikan server. Terima kasih.
Kami adalah Borg
pom.xml tidak memiliki kaitan sama sekali setelah perang telah dibuat, yaitu Tomcat (atau wadah apa pun yang Anda gunakan) tidak menggunakan file ini. File ini digunakan oleh Maven untuk membuat file perang baru, yang pada gilirannya Anda harus menyebarkan ke server. Jadi siklus ini bekerja pada kode, membuat file jar, memperbarui versi di POM perang, membuat file perang, memperbarui server dengan file perang baru. Beberapa server akan mendukung hot-deploy meskipun umumnya yang menyiratkan mematikan aplikasi selama beberapa detik.
Newtopian