--- 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