A production-ready Modular Monolith scaffold built on Spring Boot 4 and Spring Modulith.
Kiln is a starting point for Java backend services that follow the modular monolith pattern: retaining the deployment and development simplicity of a single application while using Spring Modulith's boundary verification to prevent package-level coupling from rotting over time. This leaves clear seams for later extraction into separate services if — and only if — the business actually needs it.
- Group:
com.skyflux - Artifact:
kiln - Version:
0.0.1-SNAPSHOT
| Category | Dependencies |
|---|---|
| Runtime | Java 25 (Gradle Toolchain), Spring Boot 4.0.5 |
| Architecture | Spring Modulith 2.0.5 (Core / JDBC / Runtime / Actuator / Observability) |
| Web | Spring Web MVC, Spring Security, SpringDoc OpenAPI (Swagger UI) |
| Data | Spring Data JDBC, jOOQ, Flyway migrations, Spring Data Redis |
| View | Apache FreeMarker |
| HTTP Client | Spring RestClient |
| Observability | Spring Boot Actuator, OpenTelemetry, Micrometer (OTLP & Prometheus registries) |
| Dev Tooling | Spring Boot DevTools (development only) |
| Testing | JUnit 5, Spring Boot Test, Modulith Test, REST Docs, Security Test, data slice tests |
| Build | Gradle (Groovy DSL), Asciidoctor (for REST Docs rendering) |
- JDK 25 — resolved automatically via Gradle Toolchain, but a local install is recommended for IDE support.
- Gradle — use the bundled Wrapper (
./gradlew); no separate install required. - Redis — a reachable Redis instance is needed at runtime.
- Relational database — schema is managed by Flyway; configure
spring.datasource.*inapplication.yaml.
git clone <your-repo-url> kiln
cd kiln./gradlew bootRunDefaults to Spring Boot's port 8080. Override with --args='--server.port=9000'.
./gradlew testOn success, Spring REST Docs snippets are written to build/generated-snippets.
./gradlew asciidoctor./gradlew bootJar
java -jar build/libs/kiln-0.0.1-SNAPSHOT.jarThe Spring Boot Gradle plugin ships an OCI image builder — no Dockerfile required:
./gradlew bootBuildImagekiln/
├── build.gradle # Build script and dependencies
├── settings.gradle
├── gradle/wrapper/ # Gradle Wrapper
├── src/
│ ├── main/
│ │ ├── java/com/skyflux/kiln/
│ │ │ └── KilnApplication.java # Spring Boot entry point
│ │ └── resources/
│ │ └── application.yaml # Application configuration
│ └── test/
│ └── java/com/skyflux/kiln/
│ └── KilnApplicationTests.java
└── HELP.md # Spring Initializr reference links
Modulith tip: place each business domain in its own sub-package under
com.skyflux.kiln(e.g.order/,catalog/,billing/). Spring Modulith treats every such sub-package as a module boundary — cross-module calls are only allowed through types exposed in the module'sapisub-package. This is verified byApplicationModules.verify()in tests and is the whole reason to use Modulith.
Current application.yaml only declares the application name:
spring:
application:
name: kilnWhen wiring in a database, Redis, and OpenTelemetry, extend it like so:
spring:
datasource:
url: jdbc:postgresql://localhost:5432/kiln
username: kiln
password: change-me
data:
redis:
host: localhost
port: 6379
flyway:
enabled: true
locations: classpath:db/migration
management:
endpoints:
web:
exposure:
include: health, info, prometheus, metrics
otlp:
metrics:
export:
url: http://localhost:4318/v1/metricsOnce Actuator is enabled the following paths become available:
- Health check:
GET /actuator/health - Prometheus metrics:
GET /actuator/prometheus - Modulith module graph:
GET /actuator/modulith - OpenAPI document (SpringDoc):
GET /v3/api-docs - Swagger UI:
GET /swagger-ui.html
External documentation links (Spring Boot 4, Spring Modulith, jOOQ, Flyway, OpenTelemetry, REST Docs, etc.) are collected in HELP.md.
TBD.