Setup Java Spring Boot
| This documentation was generated with the assistance of AI. Please report any inaccuracies. |
End-to-end bootstrap for a new (or older, partially set-up) Spring Boot service repository built on Domain-Driven Design and hexagonal
(ports and adapters) architecture, realised as a multi-module build: a Maven reactor for Java, or for Kotlin either
a Maven reactor or a Gradle Kotlin DSL multi-project build. It interviews the user once, resolves
every Spring Boot version and dependency id against the live Spring Initializr API, records the answers — including
the language, build tool, Kotlin version, whether the project is open source, its visibility, its CI choices, its Sonar mode, and whether it ships a Hilla frontend — in a
springboot-stack.yml manifest, and then delegates all file generation to seven sub-skills (eight when
frontend: hilla).
Purpose
iru-setup-java-springboot is the top-level entry point for starting a Spring Boot microservice from nothing, or for updating a repository
that already has an older or partial setup. It announces which of the two it is doing ("from scratch" or
"updating an existing repository", with an inventory of what is absent, present, or partial) and then lets each
sub-skill ask Update / Keep as is / Replace per pre-existing artifact it owns. It
is the interviewer and orchestrator of the Spring Boot family: no other skill in that family asks the user
anything about the stack, because this one asks everything exactly once and writes the answers to a manifest the
others read back.
Four things distinguish it from iru-setup-java-library-repository, the catalog’s other bootstrap orchestrator:
-
It imposes an architecture. The module layout (
domain,application,infrastructure/,api/,boot,coverage), the direction dependencies may point, and the rule that every dependency version lives in exactly one place — the rootpom.xmlon Maven,gradle/libs.versions.tomlon Gradle — are not options; they are what the skill exists to enforce. -
It supports Java and Kotlin. Step 3 asks the implementation language (Java recommended unless the repository already has Kotlin) and, for Kotlin only, the build tool (Gradle Kotlin DSL recommended for a new repository, Maven for an existing Maven one). Java is always Maven; Java on Gradle and Groovy-DSL Gradle builds are rejected. Kotlin uses detekt/ktlint and Dokka instead of Checkstyle/PMD/SpotBugs and Javadoc, no Lombok or MapStruct, and a Kotlin version resolved from the one the chosen Boot version manages rather than from memory. The choices are recorded as
project.language,project.buildToolandproject.kotlinVersion, and every sub-skill branches on them. -
It resolves the stack from a live API rather than from memory. Spring Boot renames starter artifacts across major versions (in Boot 4.x
spring-boot-starter-webbecamespring-boot-starter-webmvc, the Testcontainers modules becametestcontainers-<engine>, and every starter gained aspring-boot-starter-<x>-testcompanion), so the skill readshttps://start.spring.io/metadata/clientfor the current version list and dependency catalogue, and fetches a referencepom.xmlfromhttps://start.spring.io/pom.xmlfor the exact artifact names. If that API is unreachable it stops rather than guessing. -
It produces a deployable service, not a publishable library. There is no Maven Central publishing or GPG signing; instead there is a container image, OpenTofu infrastructure-as-code for AWS or Google Cloud, and deploy and undeploy workflows.
Java 21 is the enforced minimum, in maven.compiler.release, java.version, and a maven-enforcer-plugin
requireJavaVersion rule on Maven, or the JDK toolchain on Gradle — even though Spring Initializr’s own default
javaVersion is currently lower.
Plugin
Shipped by the iru-springboot plugin of the ai-catalog marketplace (install with /plugin install iru-springboot@ai-catalog; see Plugins).
Invocation
/iru-setup-java-springboot
Optionally with args (key/value lines) to pre-resolve some questions and skip the matching interview step,
whether invoked directly or driven by another orchestrator such as Setup Repository:
mode: new
open-source: yes
sonar: cloud
sonar-organization: example-github
sonar-project-key: example_orders-service
sonar-host-url: https://sonarcloud.io
frontend: none
accessibility: enforce
visibility: public
ci: yes
ci-tests: full
pages: yes
rolling-deployments: yes
deployment-strategy: canary
advance: hybrid
on-existing: ask
Inputs
Most inputs are collected interactively; the table below also covers the keys accepted via args (Step 0), which
pre-resolve the matching question instead of asking it.
| Argument | Required | Description | Default |
|---|---|---|---|
|
No |
|
Asked via |
|
No |
|
|
|
No |
|
Detected from the repository when not supplied |
|
No |
|
Asked via |
|
No |
|
Asked via |
|
No |
|
|
|
No |
|
Asked via |
|
No |
|
Detected via |
|
No |
|
Asked via |
|
No |
|
Asked when |
|
No |
|
Asked when |
|
No |
|
Asked when |
|
No |
|
|
groupId, artifactId, version, base Java package, service description, developer name/email/organizationUrl |
Yes |
Free-text project-identity fields asked in plain conversation in Step 2. The |
|
Spring Boot version |
Yes |
Confirmed via |
|
Java version |
Yes |
Confirmed via |
|
Kotlin version |
Derived (Kotlin only) |
Not asked: resolved from the |
The Boot-managed Kotlin version |
Deployment platform |
Yes |
|
None — user must choose |
Concurrency model |
Yes |
|
Blocking is presented as the recommendation |
Databases |
No |
Multi-select from MongoDB, Couchbase, relational (PostgreSQL or MariaDB), Elasticsearch, Neo4j, and Qdrant, each presented with the workload shape it suits. Every engine chosen also requires an index/migration tool (Flamingock, Liquibase and its MongoDB/Couchbase/Neo4j extensions, or Flyway). |
None |
Caches |
No |
Multi-select: Caffeine (local, per-node) and/or Redis (shared across replicas). |
None |
Spring Security |
No |
Yes/no, plus whether the service validates incoming JWTs ( |
No |
Spring Cloud Stream / Kafka |
No |
Yes/no, plus the directions needed (produce, consume, or both). AVRO is the message format, and an AsyncAPI specification alongside the schemas documents the topics carrying them. |
No |
REST server, gRPC server, GraphQL server |
No |
Yes/no each. All three are contract-first: specs live in |
No |
REST clients, gRPC clients, GraphQL clients |
No |
A name per downstream service; each becomes an |
None |
API mocking tool |
Only if a client was named |
Which mock stands in for the downstream services in integration tests and local runs — Microcks whenever any
gRPC or GraphQL client exists (it mocks all three protocols from the same contracts in one container), WireMock
for a REST-only service (lighter, with a |
Microcks with gRPC or GraphQL, WireMock for REST-only |
Logging, metrics, tracing |
No |
Asked individually; all three recommended. Metrics adds Prometheus/Grafana containers for local development. |
Recommended on |
Spring AI |
No |
Yes/no. If yes: the LLM providers (offered from the live catalogue), an optional vector store, and optional MCP server/client support. The user is warned first that this requires a paid provider subscription. |
No |
Dynamic configuration |
Yes |
|
Derived from the platform choice |
Other Initializr dependencies |
No |
Anything else from the live catalogue, by id or name, with a warning that entries outside the groups above are typically less relevant and some actively conflict with the contract-first hexagonal shape. |
None |
Outputs
-
springboot-stack.ymlat the repository root — the manifest recording the resolved identity, every technology choice, and alsoopenSource,sonar(mode/organization/projectKey/hostUrl),frontend(none/hilla),visibility,ci(enabled/tests/pages), and the optionaldeploy.rollingblock (enabled,strategy,advance,steps,bakeMinutes; absent means rolling deployments are disabled), with container image tags pinned. If a manifest already existed, the user chooses Update / Keep as is / Replace (oron-existingapplies). Meant to be committed; read by every sub-skill and later byiru-update-java-springboot-documentation. -
The full build (via
iru-setup-java-springboot-pom): for Maven (Java, or Kotlin + Maven) a root reactorpom.xmlplus one pom per module; for Kotlin + Gradlesettings.gradle.kts,gradle/libs.versions.toml, thebuild-logic/convention plugins, onebuild.gradle.ktsper module and the Gradle wrapper. Kotlin builds also get a rootdetekt.yml. -
The hexagonal source tree — ports, adapters, use cases, the
@SpringBootApplicationclass, per-profile configuration, migration changelogs, and an ArchUnit test enforcing the dependency direction, as Java or Kotlin sources (viairu-setup-java-springboot-modules). -
The
apis/contract tree, the OpenAPI/protobuf/GraphQL-SDL/AVRO generator wiring, and the AsyncAPI specification and documentation generators for messaging (viairu-setup-java-springboot-apis). -
When
frontend: hilla: the Vaadin/Hilla React frontend in thebootmodule — the Vaadin BOM/starters, thevaadin-maven-pluginexecution,src/main/frontend/, Vitest with lcov coverage, and ESLint/Prettier (viairu-setup-java-springboot-hilla), together with.ui-quality.ymland the Playwright UI tests that capture.ui-screenshots/across states, left-to-right/right-to-left and light/dark with axe-core checks at the chosenaccessibilitylevel. -
compose.yamland the Testcontainers integration-test harness (viairu-setup-java-springboot-testcontainers). -
An
infra/OpenTofu configuration for the chosen cloud (viairu-setup-java-springboot-platform). -
build.yml,deploy.yml,undeploy.yml, andsecurity.ymlGitHub Actions workflows plus.github/dependabot.yml(viairu-setup-java-springboot-github-workflows) — all skipped whenci: no. When rolling deployments are enabled,deploy.ymlbecomes a staged rollout and apromote.ymlworkflow is generated to advance, roll back or abort it (arollingstrategy keeps the single-jobdeploy.ymland generates nopromote.yml); the OpenTofu configuration then also carries the rollout infrastructure androllout_*outputs. -
An Antora documentation site with Mermaid and Kroki and the full service page set (via
iru-update-java-springboot-documentation). -
Repository-level supporting files:
.gitignore,README.md,CHANGELOG.md,checkstyle.xml(Java only; an existing one is kept), and optionallyLICENSE. On Kotlin buildsdetekt.ymlis expected from the pom sub-skill and reported as a gap if missing. -
A final report with the setup mode and, per component, the action taken (created / updated / replaced / kept as is / skipped (ci: no)), consolidating the open-source/visibility/CI/Sonar/frontend choices, whether rolling deployments are enabled (strategy, advance mode, steps and bake minutes, whether
promote.ymlwas generated, therollout_*outputs and prerequisites, the cost note that blue/green temporarily doubles capacity, and that/iru-springboot-rolling-deployments enable|disableswitches it later) (and, whenfrontend: hilla, theaccessibilitylevel, the.ui-quality.ymlaction, and whatiru-setup-java-springboot-hillareported back), every secret and variable that must be supplied out-of-band (the Sonar token only whensonar.modeis notnone, plusGITLEAKS_LICENSEif a Pro key is used), every open gap, and the result of the three verification builds (Maven or Gradle, as run).
The generated files' bytes come from template files under templates/ (and, where a template needs variant-specific notes, reference/) in .claude/skills/iru-setup-java-springboot/; the skill reads only the files for the variant it resolved, not the whole set, which keeps its SKILL.md small.
Execution flow
Dependencies
Invokes
Each of the following is invoked via the iru-isolated-skill-executor
agent rather than a direct Skill call, in this order — every sub-skill reads springboot-stack.yml and the
filesystem directly, so only a short completion summary needs to come back:
-
Setup Java Spring Boot Poms — Step 8, first: the root reactor pom and every module pom. Generates the Maven reactor, or the Gradle KTS settings/catalog/convention plugins/wrapper for Kotlin + Gradle, reading the language and build tool from the manifest. Also receives the path to the Initializr reference build saved in Step 7. If this reports that the root pom was not written (or an existing non-reactor pom was kept), the whole run stops. Receives
mode, andon-existingonly when it arrived viaargs. -
Setup Java Spring Boot Modules — Step 8: the source tree (Java or Kotlin), ports, adapters, profiles, and the ArchUnit test. Runs after the poms because it writes sources into modules rather than creating them.
-
Setup Java Spring Boot APIs — Step 8: the
apis/contracts, the code generators, and the AsyncAPI documentation generators. Runs after the modules because generated sources need a module to land in. -
Setup Java Spring Boot Hilla — Step 8, sub-step 3b, only when the manifest’s
frontend: hilla: the Vaadin/Hilla React frontend scaffolded into thebootmodule. Runs after the APIs (thebootmodule and API-generated code it may call must already exist) and before Testcontainers (the compose stack and CI docs job need to know a frontend toolchain now exists on disk). -
Setup Java Spring Boot Testcontainers — Step 8:
compose.yamland the integration-test harness. Runs after the APIs (and Hilla, when present) because the compose stack must know whether a schema registry is needed. -
Setup Java Spring Boot Platform — Step 8: the OpenTofu configuration. When
deploy.rolling.enabledis true it also receivesrolling: yes,deployment-strategy,advance,stepsandbake-minutes(alongsidemode/on-existing) and generates the rollout infrastructure;rolling: noor nothing when disabled. -
Setup Java Spring Boot GitHub Workflows — Step 8: the build, deploy, undeploy and security workflows plus Dependabot, using Maven or
./gradlewcommands and Javadoc or Dokka per the manifest. When rolling deployments are enabled it generates a stageddeploy.ymland thepromote.ymlworkflow (receiving the samerolling:/deployment-strategy:/advance:/steps:/bake-minutes:lines). Readsvisibility,ci.testsandci.pagesfrom the manifest. Skipped entirely whenci.enabled: false. Runs late because it surveys what is actually on disk. -
Update Java Spring Boot Documentation — Step 8, last: the Antora site and the service page set, derived from the finished codebase, with commands and samples matching the manifest’s build tool and language.
Rolling deployments can be switched on or off after the bootstrap with Spring Boot Rolling Deployments, which edits the manifest’s
deploy.rolling block and re-runs the platform and workflows sub-skills.
In Step 9 it also invokes directly, if available, Setup Java Gitignore,
Setup Readme, and Setup Changelog for the repository-level files the
Spring Boot sub-skills don’t own (forwarding ci, pages and sonar to the README skill, and on-existing when it
arrived via args). It additionally recommends — but does not invoke —
Check License for license headers and Check Security for secret
scanning, the latter specifically if an LLM API token may ever have been committed.
Invoked by
-
Setup Repository — Step 4, Spring Boot (Java/Kotlin, optional Hilla) bootstrap, via the
iru-isolated-skill-executoragent.
Related agents
-
iru-isolated-skill-executor— spawned once per sub-skill in Step 8, so each sub-skill’s (seven, eight whenfrontend: hilla) template expansion, file reads, and build output don’t accumulate in this orchestrator’s context over a single bootstrap run. -
iru-gate-runner— spawned for each of Step 10’s three verification runs (Maven or Gradle), so a multi-module build log never lands in this conversation.
Source
SKILL.md on GitHub — the file this page was generated from.