Getting Started¶
Prerequisites¶
All runnable examples in this playbook require:
- Java 25 (via SDKMAN:
sdk install java 25-tem) - Maven 3.9+ (included as
./mvnwwrapper in each example) - Docker (for Testcontainers in integration tests)
Running an example¶
Each pattern has a self-contained Maven project under examples/:
git clone https://github.com/marvinrichter/jvm-modernisation-playbook
cd jvm-modernisation-playbook/examples/strangler-fig # or branch-by-abstraction / acl
./mvnw spring-boot:run
Run the tests:
How the examples are structured¶
Each example contains:
| Directory | Purpose |
|---|---|
src/main/java/de/marvinrichter/<pattern>/legacy/ |
The legacy code you're migrating away from |
src/main/java/de/marvinrichter/<pattern>/newservice/ |
The target hexagonal implementation |
src/main/resources/application.properties |
Feature flags and configuration |
src/test/ |
Integration tests showing both old and new paths work |
Pattern selection guide¶
Not sure which pattern fits your situation?
Is the legacy code accessed via HTTP?
YES → Strangler Fig
NO → Is it a single class/service with a clear interface?
YES → Branch-by-Abstraction
NO → Does the new system use a different domain model?
YES → Anti-Corruption Layer
NO → Branch-by-Abstraction + Anti-Corruption Layer (combine them)
Relationship to spring-hexagonal-archetype¶
The "after" state in every example matches the package structure generated by
spring-hexagonal-archetype.
If you're starting a greenfield service alongside your legacy system, use the archetype
to generate it — then use the patterns here to route traffic into it.