Multi-Module Reactor Basics
Learn Maven In Action - Part 015
Multi-module reactor basics: aggregation, module graph, reactor sorting, partial builds, resume strategy, and failure modes for large Maven projects.
Part 015 — Multi-Module Reactor Basics
Target: setelah bagian ini, kamu tidak lagi melihat multi-module Maven sebagai “folder berisi banyak project”, tetapi sebagai build graph yang dikumpulkan, disortir, dipotong, dilanjutkan, dan dieksekusi oleh Maven reactor.
Multi-module Maven sering terlihat sederhana:
<modules>
<module>domain</module>
<module>application</module>
<module>adapter-postgres</module>
<module>service</module>
</modules>
Tapi di production, bagian ini sering menjadi sumber build lambat, dependency cycle, CI tidak deterministik, local build yang beda dari pipeline, dan release yang sulit dipahami.
Maven reactor adalah mekanisme di Maven core yang menangani multi-module build. Dokumentasi resmi Maven menjelaskan bahwa reactor melakukan tiga hal utama: mengumpulkan module yang tersedia, mengurutkan project ke build order yang benar, lalu membangun selected projects secara berurutan. Referensi: Apache Maven — Guide to Working with Multiple Modules.
1. Skill yang Ingin Dibangun
Di akhir part ini, kamu harus bisa:
- Membedakan parent, aggregator, module, dan reactor.
- Menjelaskan kenapa
<modules>bukan dependency declaration. - Membaca dan memprediksi build order multi-module.
- Menggunakan
-pl,-am,-amd, dan-rfdengan aman. - Mendesain partial build workflow untuk local development dan CI.
- Mendiagnosis failure khas reactor: missing module, wrong build order assumption, stale local artifact, hidden dependency, dan circular dependency.
Mental model utama:
multi-module Maven project = collection of Maven projects
reactor = runtime build plan over that collection
Folder structure hanyalah input kasar. Yang dieksekusi Maven adalah reactor graph.
2. Empat Konsep yang Sering Tertukar
2.1 Parent POM
Parent POM adalah POM yang diwarisi oleh child POM lewat <parent>.
Tujuannya:
- mewariskan
groupId/version, - menaruh
dependencyManagement, - menaruh
pluginManagement, - menaruh shared properties,
- menaruh build policy.
Contoh:
<parent>
<groupId>com.acme.platform</groupId>
<artifactId>acme-parent</artifactId>
<version>1.12.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
Parent menjawab pertanyaan:
“Konfigurasi build apa yang diwarisi module ini?”
2.2 Aggregator POM
Aggregator POM adalah POM yang mencantumkan module lewat <modules>.
Tujuannya:
- mengumpulkan beberapa project,
- membuat Maven menjalankan build ke module-module itu,
- membentuk input awal untuk reactor.
Contoh:
<packaging>pom</packaging>
<modules>
<module>bom</module>
<module>domain</module>
<module>application</module>
<module>service</module>
</modules>
Aggregator menjawab pertanyaan:
“Project mana saja yang dibangun bersama ketika command dijalankan dari root ini?”
Dokumentasi Maven menegaskan bahwa project aggregation berbeda dari inheritance: aggregation mencantumkan module dari parent/aggregator POM, sedangkan inheritance membuat child menunjuk ke parent POM. Referensi: Apache Maven — Introduction to the POM: Project Aggregation.
2.3 Module
Module adalah Maven project lain yang dicantumkan oleh aggregator.
<module> berisi path relatif ke directory module atau file POM.
<modules>
<module>order-api</module>
<module>order-service</module>
<module>tools/schema-generator/pom.xml</module>
</modules>
Module menjawab pertanyaan:
“POM mana yang masuk ke kumpulan build ini?”
2.4 Reactor
Reactor adalah build plan runtime yang dibentuk Maven setelah membaca project-project dalam multi-module build.
Reactor menjawab pertanyaan:
“Dari semua project yang tersedia, mana yang harus dibangun, dalam urutan apa, dan apa yang terjadi ketika sebagian build gagal?”
Satu project bisa:
- punya parent tapi tidak di-aggregate oleh parent itu,
- di-aggregate oleh aggregator tapi tidak inherit dari aggregator itu,
- inherit dan di-aggregate oleh POM yang sama,
- ikut reactor hanya ketika command dijalankan dari root aggregator tertentu.
Ini sumber banyak kebingungan.
3. Parent vs Aggregator: Jangan Campur Secara Mental
Maven mengizinkan POM yang sama menjadi parent sekaligus aggregator. Ini umum, tapi bukan kewajiban.
Di diagram ini:
- garis solid = aggregation,
- garis putus-putus = inheritance,
- garis dependency = artifact dependency.
Tiga relasi ini berbeda.
| Relasi | Dinyatakan di mana? | Efek utama | Apakah memengaruhi classpath? |
|---|---|---|---|
| Inheritance | child <parent> | konfigurasi diwarisi | tidak langsung |
| Aggregation | aggregator <modules> | module ikut reactor | tidak |
| Dependency | child <dependencies> | artifact masuk graph dependency | ya, tergantung scope |
Rule praktis:
Jangan pernah menganggap “ada di
<modules>” berarti “bisa dipakai di compile classpath”. Untuk memakai class dari module lain, tetap harus declare dependency.
Contoh salah:
<!-- root pom -->
<modules>
<module>order-domain</module>
<module>order-service</module>
</modules>
Lalu order-service memakai class dari order-domain tanpa dependency.
Itu salah. Aggregation bukan dependency.
Yang benar:
<!-- order-service/pom.xml -->
<dependencies>
<dependency>
<groupId>com.acme.order</groupId>
<artifactId>order-domain</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
4. Minimal Multi-Module Project
Struktur:
order-platform/
pom.xml
order-domain/
pom.xml
src/main/java/...
order-application/
pom.xml
src/main/java/...
order-service/
pom.xml
src/main/java/...
Root POM:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.acme.order</groupId>
<artifactId>order-platform</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>order-domain</module>
<module>order-application</module>
<module>order-service</module>
</modules>
</project>
Child POM:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.acme.order</groupId>
<artifactId>order-platform</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>order-domain</artifactId>
</project>
Command:
mvn verify
Ketika command dijalankan dari root, Maven membaca root POM, menemukan <modules>, mengumpulkan module, membentuk reactor, menyortir, lalu menjalankan lifecycle sampai phase verify untuk selected projects.
5. Reactor Sorting: Urutan <modules> Bukan Urutan Final
Banyak engineer junior berpikir Maven membangun module sesuai urutan di <modules>. Itu hanya benar ketika tidak ada relasi lain yang menentukan urutan.
Maven reactor sorting menghormati relasi berikut:
- project dependency pada module lain dalam reactor,
- plugin declaration ketika plugin adalah module lain dalam reactor,
- plugin dependency pada module lain dalam reactor,
- build extension declaration pada module lain dalam reactor,
- urutan
<modules>jika tidak ada rule lain yang berlaku.
Elemen dependencyManagement dan pluginManagement tidak menyebabkan perubahan reactor sort order karena belum tentu dependency/plugin itu benar-benar dipakai. Referensi: Apache Maven — Reactor Sorting.
Contoh:
<modules>
<module>order-service</module>
<module>order-application</module>
<module>order-domain</module>
</modules>
Jika dependency-nya seperti ini:
Maka Maven harus membangun:
order-domain
order-application
order-service
Bukan sesuai urutan deklarasi.
Urutan <modules> tetap berguna untuk readability dan tie-breaker, tapi bukan sumber kebenaran dependency order.
6. Build Order Bukan Arsitektur
Build order adalah konsekuensi teknis dari dependency graph. Ia tidak otomatis berarti desainnya bagus.
Contoh build order yang legal tapi buruk:
Masalah:
servicebergantung ketest-support,test-supportbergantung ke adapter,- adapter bergantung ke service,
- ini cenderung menyebabkan cycle atau test artifact leakage.
Maven bisa membantu menemukan problem, tapi tidak bisa menggantikan desain boundary.
Rule senior:
Reactor graph harus menjadi bayangan dari architecture dependency direction. Jika reactor graph terlihat kusut, architecture graph mungkin juga kusut.
7. Partial Build: -pl, -am, -amd, -rf
Di project besar, menjalankan mvn verify dari root untuk setiap perubahan bisa terlalu mahal. Maven menyediakan opsi untuk memotong reactor.
Dokumentasi Maven menyebut beberapa command line switches untuk reactor, termasuk --resume-from, --also-make, --also-make-dependents, --fail-fast, --fail-at-end, dan --non-recursive. Referensi: Apache Maven — Multiple Modules Command Line Options.
Short aliases umum:
| Long Option | Short Option | Makna |
|---|---|---|
--projects | -pl | pilih project/module tertentu |
--also-make | -am | ikut build dependencies dari selected project |
--also-make-dependents | -amd | ikut build dependents dari selected project |
--resume-from | -rf | lanjutkan reactor dari project tertentu |
--non-recursive | -N | build current project saja, tanpa module |
7.1 Build Satu Module Saja
mvn -pl order-service verify
Makna:
Build hanya
order-servicedari reactor.
Risiko:
- dependency module lain tidak ikut dibangun,
- Maven bisa memakai artifact lama dari local repository,
- hasil bisa berbeda dari clean full reactor build.
Gunakan ini hanya jika kamu yakin upstream dependency sudah valid di local repo.
7.2 Build Module dan Dependencies-nya
mvn -pl order-service -am verify
Makna:
Build
order-servicedan semua module dalam reactor yang dibutuhkan olehorder-service.
Jika graph:
Command:
mvn -pl order-service -am verify
Akan membangun kira-kira:
shared-kernel
order-domain
order-application
order-service
Ini command local development paling aman untuk bekerja pada deployable module tertentu.
7.3 Build Module dan Dependents-nya
mvn -pl order-domain -amd verify
Makna:
Build
order-domaindan semua module yang bergantung padanya.
Ini cocok ketika kamu mengubah module rendah/lower-level dan ingin tahu dampaknya.
Jika graph:
Command:
mvn -pl order-domain -amd verify
Akan membangun:
order-domain
order-application
order-service
order-reporting
7.4 Build Module, Dependencies, dan Dependents
mvn -pl order-application -am -amd verify
Makna:
Build selected project, dependencies-nya, dan downstream projects yang bergantung padanya.
Ini berguna untuk impact testing, tapi bisa menjadi hampir full build pada graph yang highly connected.
7.5 Resume dari Module yang Gagal
mvn -rf order-service verify
Makna:
Lanjutkan build dari
order-service.
Dipakai setelah full reactor gagal di tengah.
Tapi hati-hati: -rf tidak otomatis memperbaiki upstream state. Jika kamu mengubah upstream setelah failure, lebih aman:
mvn -pl order-service -am verify
Atau ulang dari root:
mvn verify
8. Failure Strategy: Fail Fast vs Fail At End
Default Maven adalah fail-fast: ketika satu module gagal, build berhenti.
mvn verify
Untuk CI feedback pada banyak module independen, kamu kadang ingin melihat semua failure sekaligus:
mvn --fail-at-end verify
Makna:
- Maven tetap melanjutkan module yang tidak bergantung pada module gagal,
- failure dilaporkan di akhir.
Gunakan --fail-at-end untuk:
- nightly build,
- validation branch besar,
- migration build,
- multi-module refactoring.
Gunakan default fail-fast untuk:
- pull request cepat,
- local development,
- pipeline mahal,
- ketika satu module gagal biasanya membuat downstream meaningless.
Jangan gunakan --fail-never untuk pipeline quality gate. Itu menyembunyikan failure.
9. Local Repository Trap pada Partial Build
Ini salah satu jebakan terbesar multi-module Maven.
Misal:
Kamu mengubah order-domain, lalu menjalankan:
mvn -pl order-service test
Jika order-domain tidak ikut reactor, Maven akan resolve order-domain dari local repository ~/.m2/repository.
Kemungkinan:
- artifact lama dipakai,
- test lolos padahal full reactor gagal,
- bug baru tidak terlihat,
- developer lain/CI mendapat hasil berbeda.
Command yang lebih aman:
mvn -pl order-service -am test
Rule:
Jika selected module bergantung pada module lain yang mungkin berubah, gunakan
-am.
Untuk mengecek artifact yang dipakai:
mvn -pl order-service dependency:tree
Atau dengan verbose/debug:
mvn -pl order-service -X test
10. Aggregator Goal vs Normal Goal
Sebagian plugin goal bersifat aggregator: goal itu berjalan pada aggregator/root dan memproses beberapa module sebagai satu kesatuan.
Contoh umum di dunia Maven:
- aggregate report,
- aggregate javadoc,
- release-related workflow,
- site/reporting tertentu,
- custom enterprise plugin untuk cross-module validation.
Masalah muncul ketika engineer mengira semua goal berjalan sama di setiap module.
Mental model:
normal goal = dieksekusi per project/module sesuai lifecycle/execution
aggregator goal = dieksekusi dengan awareness terhadap reactor/session/module collection
Ketika membuat custom plugin nanti, ini akan dibahas lebih dalam. Untuk sekarang, cukup pahami bahwa tidak semua plugin goal bersifat per-module murni.
Diagnostic path:
mvn help:describe -Dplugin=<plugin-prefix> -Ddetail
Cari informasi goal dan parameter. Untuk plugin resmi, baca halaman goal tersebut.
11. Struktur Root yang Sehat
Untuk project enterprise, root POM jangan dijadikan tempat semua hal tanpa batas.
Struktur awal yang sehat:
order-platform/
pom.xml # aggregator, maybe parent
order-platform-bom/
pom.xml # dependencyManagement export
order-parent/
pom.xml # optional parent if separated
order-domain/
pom.xml
order-application/
pom.xml
order-adapter-postgres/
pom.xml
order-adapter-kafka/
pom.xml
order-service/
pom.xml
order-test-support/
pom.xml
Namun untuk banyak tim, root yang menjadi parent sekaligus aggregator masih praktis:
order-platform/
pom.xml # parent + aggregator
order-bom/
order-domain/
order-application/
order-service/
Yang penting bukan apakah parent dan aggregator dipisah atau digabung. Yang penting adalah:
- inheritance tidak dipakai untuk menyembunyikan dependency,
- aggregation tidak dipakai sebagai pengganti dependency,
- BOM tidak dipakai sebagai parent sembarangan,
- deployable module tidak menjadi dumping ground semua module lain.
12. Anti-Pattern: Root POM sebagai God Object
Root POM yang buruk biasanya berisi:
- semua dependency version,
- semua plugin configuration,
- semua profile environment,
- semua repository,
- semua release config,
- semua generated source config,
- semua test config,
- semua module list,
- semua property random.
Akibat:
- setiap module mewarisi konfigurasi yang tidak relevan,
- plugin execution terjadi pada module yang salah,
- perubahan kecil root POM memicu dampak besar,
- sulit tahu module mana yang benar-benar butuh konfigurasi tertentu,
- build lambat karena plugin berjalan di terlalu banyak tempat.
Pattern lebih sehat:
root aggregator
minimal build-wide identity and module list
parent POM
shared policy and pluginManagement
BOM POM
dependency version alignment only
module POM
explicit dependencies and module-specific plugin executions
Tidak harus selalu dipisah fisik menjadi empat POM, tapi secara konsep harus dipisah.
13. Dependency Direction untuk Multi-Module
Contoh struktur layered:
Pertanyaan desain:
- Apakah
domaintahupostgres? Seharusnya tidak. - Apakah
applicationtahu framework transport? Biasanya tidak. - Apakah
adapterboleh depend keapplication? Ya, adapter menjalankan use case. - Apakah deployable module bergantung pada semua adapter? Sering iya, sebagai composition root.
Maven tidak memaksa arsitektur ini. Maven hanya mengeksekusi dependency graph yang kamu deklarasikan.
Senior engineer memakai reactor graph sebagai alat audit:
mvn dependency:tree
Lalu bertanya:
“Apakah arah dependency ini sesuai dependency rule arsitektur?”
14. Module Boundary Checklist
Sebelum membuat module baru, jawab:
- Apakah module ini punya artifact boundary yang jelas?
- Apakah ia akan dipakai oleh module lain?
- Apakah ia perlu lifecycle/test/release sendiri?
- Apakah ia menyembunyikan dependency teknis tertentu?
- Apakah module ini hanya dibuat karena folder sudah terlalu besar?
- Apakah ada risiko dependency cycle?
- Apakah module ini akan dipublish sebagai artifact internal?
- Apakah ownership module jelas?
- Apakah build time bertambah sepadan dengan boundary yang diperoleh?
- Apakah module ini membuat public API baru yang perlu dijaga?
Jangan membuat module hanya karena package Java sudah besar. Package adalah boundary source. Maven module adalah boundary build/artifact.
15. Reactor Cycle: Build System Menolak Desain yang Berputar
Contoh cycle:
Maven tidak bisa membangun graph ini secara valid karena tidak ada module yang bisa dibangun pertama tanpa membutuhkan module lain.
Solusi bukan “memaksa order”. Solusi adalah memecah boundary.
Contoh refactor:
Pattern umum untuk memutus cycle:
- ekstrak API/contract module,
- ekstrak SPI/interface module,
- pindahkan implementation ke adapter module,
- ubah dependency langsung menjadi event/message contract,
- pindahkan test fixture ke
test-supportdengan scopetest, bukan compile.
16. Common Reactor Commands for Daily Work
Full verification
mvn clean verify
Gunakan ketika:
- sebelum push besar,
- sebelum release,
- setelah update dependency/plugin,
- setelah refactoring cross-module.
Fast module verification with upstream modules
mvn -pl order-service -am verify
Gunakan ketika:
- bekerja pada satu service,
- ada upstream module yang ikut berubah,
- ingin menghindari stale local artifact.
Impact check for lower-level module
mvn -pl order-domain -amd test
Gunakan ketika:
- mengubah domain/core/shared library,
- ingin tahu downstream yang terdampak.
Resume after failure
mvn -rf order-service verify
Gunakan ketika:
- full reactor gagal di module tertentu,
- kamu memperbaiki failure di module itu,
- upstream belum berubah.
Build root only
mvn -N validate
Gunakan untuk:
- validasi root POM,
- cek effective settings/root metadata,
- operasi yang tidak perlu module recursion.
17. CI Strategy for Reactor Builds
Untuk CI, jangan asal menjalankan mvn clean install.
Pertama, pahami tujuan pipeline.
| Pipeline | Command kandidat | Tujuan |
|---|---|---|
| Pull request cepat | mvn -pl changed-module -am verify | validasi area terdampak |
| Pull request conservative | mvn -pl changed-module -am -amd verify | validasi upstream + downstream |
| Main branch | mvn clean verify | full confidence |
| Nightly | mvn clean verify --fail-at-end | kumpulkan semua failure |
| Release | mvn clean deploy | publish artifact |
Jangan gunakan install di CI kecuali ada alasan. Untuk validasi normal, verify biasanya cukup. Dokumentasi Maven sendiri menyebut verify sebagai common build invocation ketika tidak perlu reuse artifact dari local repository project lain. Referensi: Apache Maven — Running Maven.
install menulis artifact ke local repository runner. Pada ephemeral CI runner, efeknya sering tidak berguna kecuali step berikutnya dalam job yang sama perlu artifact dari local repo.
18. Build Cache dan Reactor
Maven default tidak memiliki remote build cache seperti beberapa build system lain. Yang sering disebut “cache” di Maven biasanya:
- local repository cache,
- dependency download cache,
- plugin artifact cache,
- CI workspace cache,
- repository manager proxy cache.
Jangan samakan dependency cache dengan build output cache.
Jika module tidak dibangun ulang tapi artifact lama ada di ~/.m2, Maven bisa resolve artifact lama. Itu bukan incremental correctness guarantee. Itu hanya repository resolution.
Rule:
Local repository mempercepat resolution, bukan membuktikan build output masih valid terhadap source terbaru.
19. Diagnostic Playbook: “Kenapa Module Ini Tidak Dibangun?”
Langkah:
19.1 Pastikan command dijalankan dari aggregator yang benar
pwd
ls pom.xml
Cek root POM:
grep -n "<modules>" -n pom.xml
19.2 Pastikan module tercantum
<modules>
<module>order-service</module>
</modules>
Path harus relatif dari aggregator POM.
19.3 Pastikan tidak memakai -N
mvn -N verify
-N berarti non-recursive. Module tidak ikut.
19.4 Pastikan -pl tidak mengecualikan module
mvn -pl order-api verify
Command ini memilih order-api saja. Module lain tidak ikut kecuali -am/-amd.
19.5 Pastikan module bukan hanya dependencyManagement
Jika module hanya muncul di dependencyManagement, itu tidak membuatnya ikut reactor sorting sebagai dependency aktif.
Harus ada dependency nyata bila artifact dipakai:
<dependencies>
<dependency>
<groupId>com.acme.order</groupId>
<artifactId>order-domain</artifactId>
</dependency>
</dependencies>
20. Diagnostic Playbook: “Kenapa Build Order Berbeda dari <modules>?”
Jawaban umum:
Karena Maven topologically sorts reactor projects berdasarkan dependency/plugin/build-extension relationship.
Langkah:
- Jalankan build dengan output normal dan lihat reactor order.
- Cek dependency antar module.
- Cek plugin declaration yang menunjuk module dalam reactor.
- Cek plugin dependency.
- Cek build extension.
- Baru cek urutan
<modules>sebagai fallback.
Command:
mvn -DskipTests validate
Maven biasanya menampilkan Reactor Build Order di awal output untuk multi-module build.
21. Diagnostic Playbook: “Kenapa Local Build Lolos tapi CI Gagal?”
Penyebab umum:
- local repository berisi artifact lama yang tidak ada di CI,
- module tidak ikut build karena command local memakai
-pltanpa-am, - parent POM resolved dari local repository, bukan source tree,
- profile aktif berbeda,
- JDK berbeda,
- settings.xml berbeda,
- repository mirror berbeda,
- generated source tidak committed dan tidak generated di CI.
Clean-room test:
mvn -Dmaven.repo.local=/tmp/clean-m2 clean verify
Ini memaksa Maven memakai local repository kosong khusus command itu. Sangat berguna untuk menemukan dependency yang diam-diam hanya ada di laptop.
22. Good Defaults untuk Multi-Module Team
Untuk repo enterprise, gunakan rule berikut:
- Command standar lokal:
mvn -pl <module> -am verify
- Command standar sebelum merge besar:
mvn clean verify
- Main branch pipeline:
mvn clean verify
- Nightly/full migration:
mvn clean verify --fail-at-end
-
Jangan mengandalkan
mvn installsebagai cara normal agar module saling melihat. -
Jangan commit workaround yang hanya memperbaiki local reactor tapi merusak published artifact.
-
Setiap module harus punya alasan boundary yang jelas.
23. Exercise: Prediksi Reactor Build
Struktur:
platform/
pom.xml
api/
domain/
app/
postgres-adapter/
service/
Dependencies:
Pertanyaan:
- Apa build order untuk
mvn verify? - Apa yang dibangun oleh
mvn -pl service -am verify? - Apa yang dibangun oleh
mvn -pl domain -amd test? - Apa risiko
mvn -pl service test?
Jawaban:
api,domain,app,postgres-adapter,service.api,domain,app,postgres-adapter,service.domain,app,postgres-adapter,service.apitidak ikut kecuali dibutuhkan sebagai dependency dari selected/dependent graph yang dipilih dan resolusinya membutuhkan reactor build; untuk command conservative, gunakan-am -amd.servicebisa memakai artifact lama dari local repository untuk upstream module.
24. Senior Review Checklist
Saat review PR multi-module Maven, cek:
- Apakah module baru benar-benar perlu artifact boundary?
- Apakah dependency direction sesuai arsitektur?
- Apakah ada dependency cycle tersembunyi?
- Apakah
test-supportmasuk compile scope? - Apakah root POM makin menjadi god object?
- Apakah module order di
<modules>readable? - Apakah command CI memakai
verify, bukaninstalltanpa alasan? - Apakah partial build instruction memakai
-am? - Apakah parent dan aggregator sengaja digabung/dipisah?
- Apakah artifact yang dipublish punya dependency metadata benar?
25. Kesimpulan
Multi-module Maven bukan mekanisme folder. Ia adalah mekanisme build graph.
Ingat empat boundary:
parent = inheritance/config boundary
aggregator = collection boundary
module = project/artifact boundary
reactor = runtime build execution boundary
Kesalahan terbesar adalah mencampur keempatnya.
Untuk bekerja efektif:
- gunakan
<modules>untuk mengumpulkan project, - gunakan
<dependencies>untuk classpath/artifact relation, - gunakan
<parent>untuk inheritance policy, - gunakan
-pl,-am,-amd,-rfuntuk mengontrol reactor, - gunakan full
mvn clean verifyuntuk confidence tinggi.
Pada part berikutnya, kita akan naik satu level: bukan hanya bagaimana reactor bekerja, tetapi bagaimana menyusun multi-module enterprise architecture yang scalable, maintainable, dan defensible.
Referensi
You just completed lesson 15 in build core. Use the series map if you want to review the broader track, or continue directly into the next lesson while the context is still warm.
Keep the momentum while the lesson is still fresh. Move backward for review or continue forward into the next concept.