Skip to content

Repository files navigation

JPMS & DDD Study Project

A multi-module Maven project demonstrating the integration of the Java Platform Module System (JPMS) with Domain-Driven Design (DDD) and Clean / Hexagonal Architecture principles.

🚀 Project Overview

The objective of this project is to model a decoupled payment system with asynchronous in-memory event publishing. By leveraging JPMS modules, compile-time and run-time encapsulation are strictly enforced, while DDD patterns ensure the business logic remains pure and decoupled from infrastructure components.


🏗️ Architecture & Module Structure

The project is split into four distinct modules under a parent POM:

graph TD
    subgraph Application Layer
        App[system.application]
    end

    subgraph Infrastructure Layer
        Broker[system.messagebroker]
        Utils[system.utils]
    end

    subgraph Domain Layer
        Payment[system.payment]
    end

    App --> Payment
    App --> Broker
    App --> Utils
    Broker --> Payment
    Payment --> Utils
Loading

1. system.payment (Domain Module)

  • Purpose: Represents the core business logic of the payment subdomain.
  • Dependencies: Only depends on the utility module system.utils. It knows nothing about the message broker or application bootstrap.
  • Key Patterns:
    • Defines the Transaction entity/record and its nested CompletedEvent record.
    • Declares the Port (Interface) PaymentEventPublisher which abstraction-wise delegates the publication of domain events.
    • Encapsulates implementation details (MockPayment) within a non-exported package, exposing only the service contract (Payment) and the creator factory (PaymentFactory).

2. system.messagebroker (Generic Infrastructure Module)

  • Purpose: A reusable, domain-agnostic in-memory event bus implementing Java's Flow API (SubmissionPublisher).
  • Dependencies: None. It has no dependencies on system.payment, making it 100% reusable across other domains (e.g., inventory, ordering).
  • Key Patterns:
    • Exposes a generic EventPort interface for subscribing and publishing arbitrary events.

3. system.utils (Utility Module)

  • Purpose: Provides helper tools such as a reflection-based custom JSON serializer (Json).
  • Key JPMS Concept: Demonstrates deep reflection using the opens directive in the module-info descriptor of target classes (e.g., opening payment models to system.utils to allow reading private fields at runtime).

4. system.application (Composition Root & Orchestration)

  • Purpose: The entry point of the application. It acts as the bootstrapper that configures and wires all components.
  • Dependencies: Depends on all modules (system.payment, system.messagebroker, system.utils).
  • Key Patterns:
    • Implements the Adapter Pattern via PaymentEventPublisherAdapter to bridge the domain-specific PaymentEventPublisher interface with the generic EventPort bus.
    • Bootstraps the application, configures event listeners, and triggers mock payment executions.

🛠️ JPMS & DDD Design Choices

The Dependency Inversion Principle (DIP)

To keep the system.messagebroker generic and the system.payment domain pure, we decoupled them through an adapter in the application layer:

  1. system.payment defines a port: PaymentEventPublisher.
  2. system.messagebroker defines a generic bus: EventPort.
  3. system.application bridges them with PaymentEventPublisherAdapter, avoiding circular or domain-to-infrastructure dependencies.

Encapsulation & Reflection (opens vs exports)

  • The payment module uses exports to expose contracts (Payment, PaymentFactory, Transaction).
  • It uses opens com.watashi.system.payment.model to system.utils to permit the serializer to perform deep reflection on model classes without exposing internal fields to compiler imports.

🏁 Getting Started

Prerequisites

  • Java SDK 21 or higher
  • Apache Maven 3.9+

How to Build & Install

Run the clean install command to compile, build modular JARs, and install them into your local maven cache:

mvn clean install

How to Run the Application

Execute the bootstrap main class via the Maven exec plugin:

mvn exec:java -pl system.application

Created as a study workspace for exploring modular Java architectures.

About

Java Platform Module System (JPMS / Java 9+) reference patterns and modular architecture samples.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages