# Maven Multi-Module Project Structure and Module Dependencies in DD Poker

> Explore the Maven multi-module project structure and inter-module dependencies in DD Poker. Learn how the parent POM coordinates 23 child modules for seamless dependency management.

- Repository: [Doug Donohoe/ddpoker](https://github.com/dougdonohoe/ddpoker)
- Tags: internals
- Published: 2026-02-28

---

**The DD Poker repository implements a classic Maven aggregator architecture where a parent POM at [`code/pom.xml`](https://github.com/dougdonohoe/ddpoker/blob/main/code/pom.xml) coordinates 23 child modules sharing the `com.donohoedigital` groupId and version 3.0, with inter-module dependencies resolved automatically through standard Maven dependency declarations.**

The DD Poker open-source project demonstrates enterprise-grade Maven organization for a complex Java application spanning poker engines, network protocols, and web interfaces. Understanding its **Maven multi-module project structure and module dependencies** reveals how the codebase maintains clean separation of concerns through modular architecture and standardized build configuration.

## Parent Aggregator POM Structure

The foundation of the build system resides in [`code/pom.xml`](https://github.com/dougdonohoe/ddpoker/blob/main/code/pom.xml), which serves as both the parent and aggregator POM. This file declares the `<modules>` section listing all 23 sub-modules in exact build order, ensuring Maven compiles foundational libraries before dependent applications.

Key configurations defined in the parent include:

- **Group ID**: `com.donohoedigital` shared uniformly across all artifacts
- **Version**: `3.0` synchronized across the entire project
- **Java Target**: Java 25 via the Maven Compiler Plugin
- **Dependency Management**: Centralized version properties for Log4j2, SLF4J, Spring, Hibernate, Jetty, JUnit, and Apache Wicket

The parent POM uses `<packaging>pom</packaging>` and the artifactId `all`, distinguishing it as an aggregator rather than a deployable artifact.

## Child Module Configuration

Each module resides in a subdirectory under `code/` and inherits from the parent through a standardized POM template. The `server` module at [`code/server/pom.xml`](https://github.com/dougdonohoe/ddpoker/blob/main/code/server/pom.xml) illustrates this pattern:

```xml
<project>
  <modelVersion>4.0.0</modelVersion>
  
  <parent>
    <groupId>com.donohoedigital</groupId>
    <artifactId>all</artifactId>
    <version>3.0</version>
    <relativePath>../pom.xml</relativePath>
  </parent>
  
  <artifactId>server</artifactId>
  <packaging>jar</packaging>
  
  <dependencies>
    <dependency>
      <groupId>com.donohoedigital</groupId>
      <artifactId>common</artifactId>
      <version>3.0</version>
    </dependency>
    <dependency>
      <groupId>jakarta.servlet</groupId>
      <artifactId>jakarta.servlet-api</artifactId>
      <version>${servlet.api.version}</version>
    </dependency>
  </dependencies>
</project>

```

Child modules declare intra-project dependencies by referencing sibling `artifactId`s with the shared `groupId`. Maven resolves these automatically during the reactor build, placing dependent JARs on the classpath according to the dependency graph.

## Inter-Module Dependency Graph

The 23 modules form a directed acyclic graph that determines compilation order. The parent POM sequences modules so that foundational utilities build first, while higher-level game logic modules build last.

**Foundation modules** (no intra-project dependencies):
- `common` – Core utilities and logging
- `db` – Database abstractions
- `ddpoker` – Stand-alone poker library

**Infrastructure modules**:
- `mail` → depends on `common`
- `gui` → depends on `common`
- `server` → depends on `common`
- `udp` → depends on `common`
- `installer` → depends on `common`
- `tools` → depends on `common`

**Web and application layers**:
- `wicket` → depends on `common`, `gui`, `mail`
- `jsp` → depends on `common`, `gui`

**Game engine hierarchy**:
- `gamecommon` → depends on `server`
- `gameengine` → depends on `server`
- `gameserver` → depends on `server`, `gamecommon`
- `gametools` → depends on `common`, `gameserver`

**Poker-specific stack**:
- `pokerengine` → depends on `db`, `gamecommon`, `ddpoker`
- `pokernetwork` → depends on `pokerengine`, `udp`
- `poker` → depends on `pokerengine`, `gameengine`, `gameserver`
- `pokerserver` → depends on `pokerengine`, `gamecommon`, `mail`
- `pokerwicket` → depends on `pokerengine`, `wicket`, `gui`
- `proto` → depends on `common` (network protocol utilities)

## Practical Build Examples

### Compiling the Entire Project

To build all modules in dependency order, execute from the `code/` directory:

```bash
cd code
mvn clean install

```

Maven automatically detects the parent POM, reads the `<modules>` list, and constructs the reactor build plan. The `common` module compiles first, followed by `mail`, `gui`, and proceeding upward through `pokerengine` to `pokerwicket`.

### Adding Functionality Across Modules

When adding a feature that uses utilities from `common` within the `gui` module, import classes normally:

```java
package com.donohoedigital.myfeature;

import com.donohoedigital.common.Logging;

public class MyFeature {
    public void initialize() {
        Logging.info("Feature initialized");
    }
}

```

The [`gui/pom.xml`](https://github.com/dougdonohoe/ddpoker/blob/main/gui/pom.xml) already declares the `common` dependency, so the compiler resolves the `Logging` class without additional configuration.

### Creating a New Module

To extend the project with a new module named `analyticsserver`:

1. Create [`code/analyticsserver/pom.xml`](https://github.com/dougdonohoe/ddpoker/blob/main/code/analyticsserver/pom.xml):

```xml
<project>
  <parent>
    <groupId>com.donohoedigital</groupId>
    <artifactId>all</artifactId>
    <version>3.0</version>
    <relativePath>../pom.xml</relativePath>
  </parent>
  
  <artifactId>analyticsserver</artifactId>
  <packaging>jar</packaging>
  
  <dependencies>
    <dependency>
      <groupId>com.donohoedigital</groupId>
      <artifactId>pokerengine</artifactId>
      <version>3.0</version>
    </dependency>
  </dependencies>
</project>

```

2. Add `<module>analyticsserver</module>` to the parent [`pom.xml`](https://github.com/dougdonohoe/ddpoker/blob/main/pom.xml) in the appropriate position (after `pokerengine` in this case).

3. Run `mvn clean install` to verify the module integrates correctly into the build reactor.

### Running Multi-Module Tests

Unit tests in higher-level modules automatically receive transitive dependencies. A test class in `pokerserver` can instantiate `PokerServer` (from the same module) which internally uses `Logging` (from `common`) and `GameEvent` (from `gamecommon`), because [`pokerserver/pom.xml`](https://github.com/dougdonohoe/ddpoker/blob/main/pokerserver/pom.xml) declares:

```xml
<dependencies>
  <dependency>
    <groupId>com.donohoedigital</groupId>
    <artifactId>pokerengine</artifactId>
    <version>3.0</version>
  </dependency>
  <dependency>
    <groupId>com.donohoedigital</groupId>
    <artifactId>gamecommon</artifactId>
    <version>3.0</version>
  </dependency>
  <dependency>
    <groupId>com.donohoedigital</groupId>
    <artifactId>mail</artifactId>
    <version>3.0</version>
  </dependency>
</dependencies>

```

## Summary

- The **parent POM** at [`code/pom.xml`](https://github.com/dougdonohoe/ddpoker/blob/main/code/pom.xml) aggregates 23 modules and centralizes dependency versions for Java 25, Spring, Hibernate, and Wicket.
- **Inter-module dependencies** use the shared `com.donohoedigital` groupId and version 3.0, with Maven resolving the directed acyclic graph automatically during reactor builds.
- **Foundation modules** like `common`, `db`, and `server` provide core functionality with minimal coupling, while specialized modules like `pokerengine` and `pokerserver` compose these into game-specific logic.
- **Build order** is enforced by the parent POM's `<modules>` list, ensuring compile-time dependencies are satisfied before dependent modules build.

## Frequently Asked Questions

### How do I add a new module to the DD Poker Maven project?

Create a new directory under `code/` with a [`pom.xml`](https://github.com/dougdonohoe/ddpoker/blob/main/pom.xml) declaring the parent as `com.donohoedigital:all:3.0`, specify your `artifactId` and dependencies, then add the module name to the `<modules>` list in [`code/pom.xml`](https://github.com/dougdonohoe/ddpoker/blob/main/code/pom.xml). Position the entry after all modules your new code depends on to maintain correct build order.

### What determines the compilation order of modules?

Maven calculates the reactor build order from the `<modules>` sequence in the parent POM combined with the explicit dependency graph declared in each module's `<dependencies>` section. The parent POM lists modules such that `common` builds first, followed by infrastructure modules like `server` and `mail`, then game logic modules like `pokerengine`, and finally application modules like `pokerwicket`.

### Which modules have no dependencies on other DD Poker modules?

The `common`, `db`, and `ddpoker` modules serve as the foundation with zero intra-project dependencies. The `common` module provides logging and utility classes used by nearly every other module, while `db` offers database abstractions and `ddpoker` contains stand-alone poker logic.

### How are third-party library versions managed across all modules?

The parent POM at [`code/pom.xml`](https://github.com/dougdonohoe/ddpoker/blob/main/code/pom.xml) defines version numbers as properties (e.g., `${log4j2.version}`, `${spring.version}`). Child modules reference these properties in their dependency declarations, ensuring consistent versions of Log4j2, SLF4J, Servlet API, and testing frameworks across the entire multi-module project.