Runtime AtlasJava platform fieldbook
Java · Language to RuntimeView Markdown source

Real-life scenario: LedgerStream

LedgerStream reconciles millions of daily transactions from banks, payment providers, and SAP. It must identify mismatches, preserve an audit trail, and finish the daily batch within 45 minutes.

Requirements

  • Inputs arrive as large UTF-8 CSV/JSON files and partner HTTP APIs.
  • Money must be exact across currencies and rounding rules.
  • A duplicate file or event must not duplicate ledger effects.
  • Partner APIs may be slow for minutes.
  • A corrupt record must not stop all valid records.
  • The process must resume safely after a crash.
  • Operators need progress, mismatch counts, traces, and a reproducible report.

Domain model

Use records for validated immutable data carriers:

record Money(BigDecimal amount, Currency currency) {
  Money {
    Objects.requireNonNull(amount);
    Objects.requireNonNull(currency);
    amount = amount.setScale(currency.getDefaultFractionDigits(),
                             RoundingMode.HALF_EVEN);
  }
}

Use a sealed result hierarchy: Matched, Mismatch, and Rejected. An exhaustive switch forces handling when a new result type appears.

Processing design

Read files with NIO using bounded buffers and explicit UTF-8. Validate each row into a domain command. Compute a stable idempotency key from partner, file, and transaction identity. Persist checkpoints after bounded chunks.

Use virtual threads for independent blocking partner HTTP calls. Do not create an unbounded request storm: a semaphore caps each partner's concurrency and the connection pool remains the real scarce resource. Each call has a timeout, bounded retry with jitter for safe transient failures, and a circuit breaker in the surrounding application layer.

CPU-heavy matching uses a fixed-size platform-thread executor based on measured cores. ConcurrentHashMap stores shared indexes only where memory permits; larger joins belong in a database or external sort. Never use parallel streams for blocking partner calls.

Correctness

Use BigDecimal, explicit currency/rounding, Instant for event time, and the partner's ZoneId for business-day boundaries. Treat duplicate input as a successful replay of the previous outcome. Isolate malformed rows into a quarantine report with safe error detail.

Modules

Create modules or strongly enforced packages: ledger.domain, ledger.ingest, ledger.match, ledger.partner, ledger.report, and ledger.runtime. Domain code does not depend on file, HTTP, or database adapters.

Operations

Build with a pinned JDK 25 toolchain and reproducible JAR. Run as non-root. Record artifact checksum, source revision, input manifest, configuration, and output checksum. Use JFR during performance tests. Publish throughput, queue depth, rejected rows, partner latency, retry count, GC, and completion ETA.

Failure drill

Terminate the process halfway through. On restart, LedgerStream verifies the input manifest, resumes from a committed checkpoint, replays idempotently, and produces the same final checksums. Simulate one slow partner and prove the concurrency cap protects all others.

Decision record

Chosen: immutable records, sealed results, NIO, BigDecimal, virtual threads for blocking I/O, bounded CPU pool, checkpoints, idempotency, and JFR.

Rejected: double for money, one thread per record without limits, parallel streams for network calls, untrusted Java deserialization, and a single giant mutable map without capacity proof.

Runtime AtlasIndependent study material · verify production details in official Java documentation