Stage 4 - Multi-module Projects: Architecture for Large Builds
A single module is comfortable until one project contains API models, business services, repositories, web controllers, shared utilities, and generated clients. Then one flat project becomes hard to navigate and reuse.
A multi-module project splits one logical system into several build modules. Each module has its own artifact and dependencies, while the parent or root project coordinates the whole build.

Why this topic exists
In Maven, the parent project usually has packaging pom and a <modules> section. It can also provide common properties, dependency management, plugin configuration, and versions inherited by child modules.
An aggregator is the project that lists modules and builds them together. A parent is the project from which modules inherit configuration. In many Maven projects the same root POM is both parent and aggregator, but the concepts are different.
Typical backend modules are api, service, common, repository, and web. The web module depends on service; service depends on repository and common; api may contain DTOs or interfaces used by clients.
Dependencies between modules must point in one direction. If service depends on web, and web depends on service, the architecture is circular and the build becomes a symptom of poor boundaries.
A full build from the root should compile modules in the right order. Build tools calculate the reactor or task graph from declared module dependencies.
Build flow
- parent project.
- modules.
- shared versions.
- module dependencies.
- full build.
This sequence is the mental model to keep while reading build files. The names are different in Maven and Gradle, but the practical question is the same: what input is used, what task runs, what output is produced, and where that output is stored.
Concrete example
project
|-- api
|-- service
|-- common
|-- repository
`-- web
Useful reference
| Concept | Meaning |
|---|---|
| Parent | Provides inherited configuration. |
| Aggregator | Lists modules and builds them together. |
| Module dependency | One module uses classes or artifact from another module. |
| Reactor build | Maven build of all related modules in the right order. |
How this is used in real projects
Use modules to express real boundaries, not to create folders with extra ceremony. Good modules reduce coupling; bad modules only make the build slower.
In a team setting, build knowledge is not optional theory. It affects local development, CI time, dependency upgrades, release stability, and debugging. When a Spring service fails to start after a dependency change, when CI downloads a different library version, or when an artifact cannot be deployed, the answer is usually in the build configuration, dependency graph, packaging step, or repository setup.
Common mistakes
- Copying configuration without understanding which layer of the build it affects.
- Treating a local successful build as proof that CI and production delivery will work.
- Ignoring dependency trees, generated output, and repository rules until a release fails.
- Mixing application runtime configuration with build-time configuration.
Understanding checklist
- I can explain the main terms in this article without reading the build file aloud.
- I can draw the sequence from source code to artifact for this topic.
- I can name the command or file I would inspect first during a build problem.
Self-check questions
- What problem does this build concept solve in a real Java or Spring project?
- Which file or command gives the fastest evidence when something goes wrong?
- What mistake would make the build work locally but fail in CI or another developer environment?
Practice Before the Next Lesson
Draw a four-module project: web, service, repository, and common. Add arrows only in the direction where code is allowed to depend on another module. If you draw an arrow from repository to web, explain what architectural rule was broken.