{ "@context": "https://schema.org", "@graph": [ { "@type": "WebSite", "@id": "https://www.ggorantala.dev/#website", "url": "https://www.ggorantala.dev/", "name": "Gopi Gorantala", "description": "Staff engineer building Kafka and Flink platforms for banking. Production failures traced to root cause." }, { "@type": "Person", "@id": "https://www.ggorantala.dev/#person", "name": "Gopi Gorantala", "url": "https://www.ggorantala.dev/", "jobTitle": "Staff Software Engineer", "worksFor": { "@type": "Organization", "name": "ING Bank" }, "sameAs": [ "https://x.com/ggorantala", "https://www.linkedin.com/in/ggorantala/", "https://github.com/ggorantala", "https://leetcode.com/ggorantala" ] } ] }
Skip to content

Maven Multi-Module Projects

Learn Maven multi-module projects with examples. Understand parent POM vs child modules, aggregator vs inheritance, and see a complete multi-module setup for Java applications.

Maven Project
Gopi Gorantala

Introduction

As Java applications grow, they often need to be split into multiple modules (e.g., API layer, service layer, database layer).
Managing each module as a separate Maven project can become painful.

This is where Maven multi-module projects come in.
They allow you to structure and manage multiple related modules under a single parent project, making builds more consistent and efficient.

In this lesson, we’ll cover:

  • Parent POM and child modules
  • Aggregator vs inheritance in Maven
  • A complete multi-module project setup

1. Parent POM and Child Modules

A parent POM acts as the central configuration point for all modules.

  • It defines common dependencies, plugins, and properties.
  • Each child module inherits these settings, reducing duplication.

Example: Parent POM (pom.xml)

<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 
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>my-app</artifactId>
    <version>1.0.0</version>
    <packaging>pom</packaging>

    <!-- Modules declaration -->
    <modules>
        <module>service</module>
        <module>api</module>
        <module>database</module>
    </modules>

    <!-- Shared dependency management -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
                <version>3.1.0</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

</project>

Example: Child Module POM (service/pom.xml)

<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 
         http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <parent>
        <groupId>com.example</groupId>
        <artifactId>my-app</artifactId>
        <version>1.0.0</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>
    <artifactId>service</artifactId>

    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>api</artifactId>
            <version>1.0.0</version>
        </dependency>
    </dependencies>
</project>

📌 Here, the parent POM manages dependencies, and child modules inherit them.

2. Aggregator vs Inheritance

Multi-module projects often involve two related but different concepts:

ConceptDescriptionExample Use Case
AggregatorA POM that lists submodules using <modules>. It controls the build order and allows building all modules together.Running mvn install at the parent level builds all child modules.
InheritanceChild modules inherit configuration (dependencies, plugins, properties) from the parent POM using the <parent> tag.Avoids repeating common dependencies in every child POM.

✅ In practice, most multi-module projects use both aggregator and inheritance in the parent POM.

3. Example: Multi-Module Project Setup

Let’s build a simple employee management system with three modules:

  • api → Defines REST endpoints
  • service → Business logic layer
  • database → Handles persistence

Directory Structure

my-app/
│
├── pom.xml (Parent POM - aggregator + inheritance)
├── api/
│   └── pom.xml
├── service/
│   └── pom.xml
└── database/
    └── pom.xml

Build Commands

  • Build all modules at once: mvn clean install.
  • Build only one module (e.g., service): mvn clean install -pl service.
  • Build one module and its dependencies: mvn clean install -pl service -am.

Why Use Multi-Module Projects?

  • Consistency → Centralized dependency management
  • Efficiency → Build only what changed, not the entire project
  • Modularity → Easier to maintain and scale large applications
  • CI/CD Friendly → Optimized for pipelines where modules can be built independently

Key Takeaways

  • Multi-module projects use a parent POM to manage configuration and dependencies.
  • Aggregator (modules list) + Inheritance (shared settings) = Clean, maintainable structure.
  • Builds can be run at parent level or for specific modules.
Maven Project

Staff engineer architecting Kafka and Flink platforms for banking, where a dropped event is a reconciliation break, not a retry. Through javahandbook.com, I share production-tested guidance on building reliable event-driven systems.

Comments