---
name: multi-module-maven
description: >
Use when working in a multi-module Maven project. Covers parent POM conventions,
shared dependency management, inter-module rules, and build ordering.
---
# Multi-Module Maven
## Typical Structure
```
my-app/
├── pom.xml ← Parent POM (packaging = pom)
├── my-app-domain/ ← Pure Java domain — no Spring
│ └── pom.xml
├── my-app-application/ ← Use cases — depends on domain
│ └── pom.xml
├── my-app-infrastructure/ ← JPA, Redis, HTTP clients
│ └── pom.xml
└── my-app-web/ ← Spring Boot app, REST — depends on all above
└── pom.xml
```
## Parent POM
```xml
com.example
my-app
1.0.0-SNAPSHOT
pom
my-app-domain
my-app-application
my-app-infrastructure
my-app-web
org.springframework.boot
spring-boot-starter-parent
3.3.0
21
1.6.3
com.example
my-app-domain
${project.version}
com.example
my-app-application
${project.version}
org.mapstruct
mapstruct
${mapstruct.version}
org.apache.maven.plugins
maven-compiler-plugin
${java.version}
${java.version}
org.projectlombok
lombok
org.mapstruct
mapstruct-processor
${mapstruct.version}
```
## Child Module POM (domain — no Spring)
```xml
com.example
my-app
1.0.0-SNAPSHOT
my-app-domain
org.projectlombok
lombok
true
```
## Child Module POM (web — the runnable app)
```xml
...
my-app-web
com.example
my-app-application
com.example
my-app-infrastructure
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-maven-plugin
```
## Dependency Rules
| Module | Can depend on | Cannot depend on |
|--------|---------------|------------------|
| `domain` | Nothing | Everything |
| `application` | `domain` | `infrastructure`, `web` |
| `infrastructure` | `domain`, `application` | `web` |
| `web` | All modules | — |
## Gotchas
- Agent puts `spring-boot-maven-plugin` in parent POM — only in the runnable module
- Agent adds `` in parent instead of `` — adds to all modules' classpath
- Agent creates circular dependencies between modules — enforce the dependency direction above
- Agent imports Spring in `domain` module — domain must be framework-free
- Agent uses `${project.version}` for inter-module versions — correct, but update parent version to update all
- Agent overrides Boot-managed dependency versions without a compatibility reason - prefer the Boot BOM defaults