From weeks of guesswork to 12 minutes of certainty

Spring Boot Upgrades,
Without the Pain

An AI agent that reads every release note, scans every line of your code, validates every finding against real evidence, and delivers a pull request — while your engineers focus on building products.

0
Minutes / Scan
0
Validation Strategies
0
Release Docs Parsed
0
Unit Tests
0
Modules
The Story
Every Spring Release Was a Fire Drill

Here's what an upgrade looked like before — and what it looks like now. Same team, same services, completely different experience.

🔥 Before — The Manual Way

1

Wait for news. Someone notices a new release on Twitter or Slack. Maybe a few days late.~2–3 days lag

2

Read release notes. One engineer spends a morning reading 42 patch notes, 9 wiki pages, and StackOverflow threads that may not apply.2–3 hours

3

Manually audit the codebase. Grep for deprecated annotations, check pom.xml, Ctrl+F through application.yml. Miss things. Always miss things.3–4 hours

4

Bump versions and pray. Change the parent pom, run mvn compile, get 47 errors. Each fix needs another doc search.1–2 days

5

Write regression tests. If there's time. Usually there isn't. Ship it and hope monitoring catches the gaps.2–4 hours

6

Repeat for every microservice. You have 40 services. Some on Boot 2.7, some on 3.2. Nobody knows which config properties changed.

2–3 DaysPer service for major · 1 day for minor
VS

⚡ After — The Agent Way

1

Cron fires at 2 AM Monday. GitHub Actions triggers the agent. No human involved.0 minutes

2

Agent reads ALL the docs. 42 release notes, 9 wiki guides, recipe catalog, mvn dependency:tree output — cross-referenced against YOUR code.45 seconds

3

AI analysis + 10-strategy validation. LLM finds impacts. Agent validates each finding against actual pom.xml, config, imports, annotations. Hallucinations filtered.3 minutes

4

Automated fixes applied. OpenRewrite runs deterministic recipes. Maven bumps versions. LLM fixes remaining compile errors with retry. DOM-based pom updater handles BOM imports.5 minutes

5

Test stubs generated. JUnit 5 tests for actuator contracts, JWT auth, Jackson compatibility, observability — targeting your specific gaps.2 minutes

6

PR + report delivered. Monday morning: a clean pull request, a detailed GitHub Issue with evidence, and a dashboard showing all 40 services.Instant

12 MinutesPer service, fully automated
Business Impact
The Numbers That Matter

Real savings across a fleet of 40 microservices, based on actual engineering team data.

0%
Time Reduction
From 2–3 days of manual effort per major upgrade (1 day for minor) to 12 minutes of automated analysis. Engineers reclaim their sprint for product work.
0h
Engineering Hours Saved / Year
Across a 40-service fleet with quarterly upgrade cycles. That's 8 full engineer-weeks returned to product development.
0 CVEs
Missed Security Patches
The agent runs weekly. No more "we'll upgrade next quarter." Every Spring Security advisory scanned within 7 days.
0%
Fleet Visibility
The dashboard shows every service's current Spring Boot version, pending upgrades, risk levels, and CVE exposure — in one view.
Beyond Migration
Engineering the Next Baseline
This is not about moving from version X to Y.

It's about enabling capabilities, performance, and engineering velocity that your current stack fundamentally cannot support. Every Spring Boot generation unlocks an entirely new class of operational and architectural possibilities — not incremental improvements, but step-function leaps that compound across every service in your fleet.

The Past

The Stack That Got You Here

Boot 2.7 was solid. It shipped products, passed audits, survived peak traffic. But it was built for a world of blocking I/O, manual observability wiring, and javax namespaces. The JVM it runs on can't even use virtual threads. The libraries it pins are two generations behind. The foundations are still standing — but the ceiling is already hit.

The Present

The Widening Gap

Every month you stay on an older version, the distance between your stack and the ecosystem grows exponentially. Jackson 3.0 changed its groupId. Hibernate 7 requires Jakarta EE. Micrometer 2.x restructured its entire API. Your security team flags CVEs that will never be patched. New hires ask why the codebase uses patterns from 2019. The upgrade doesn't get easier with time — it gets dramatically harder.

The Future

What the Next Baseline Unlocks

Boot 4.0+ on Java 21/25 isn't an incremental update — it's a platform shift. Virtual threads eliminate thread-pool tuning. Native OpenTelemetry replaces manual wiring. GraalVM native images cut cold starts to milliseconds. Every service gets faster, more observable, and more secure — not because you wrote better code, but because the platform does the heavy lifting.

The question isn't whether to upgrade — it's how much capability you're willing to leave on the table while you wait.

— The Compound Cost of Standing Still

What the Upgrade Actually Unlocks

Virtual Threads

Eliminate thread-pool tuning entirely. IO-bound services see 3-5x throughput improvements with zero code changes. Boot 4.0 auto-configures them.

Java 21+
📡

Native OpenTelemetry

Replace manual Micrometer+OTel wiring with built-in OTLP export. Traces, metrics, and logs unified out of the box.

Boot 4.0
🔒

Zero-Day Security

Active OSS support means every Spring Security CVE gets patched within days. Your fleet stays secure without heroic manual effort.

Continuous
🚀

GraalVM Native Images

Production-ready native compilation. Sub-second startup times. 80% less memory. Perfect for serverless and auto-scaling workloads.

Boot 4.0
🧩

Ecosystem Compatibility

Jackson 3.0, Hibernate 7, Micrometer 2.x, Spring Security 7 — the entire Java ecosystem has moved forward. Your dependencies should too.

Library Alignment
💎

Developer Velocity

Pattern matching, sealed classes, records, and modern APIs make code cleaner, more expressive, and easier to maintain. New engineers onboard faster.

Java 21/25

Official Spring Boot Support Timeline

Source: spring.io/projects/spring-boot — as of April 2026

VersionReleasedOSS Support EndsCommercial EndsStatus (Apr 2026)
4.1.xMay 2026Jun 2027Jun 2028Upcoming
4.0.xNov 2025Dec 2026Dec 2027✅ Active
3.5.xMay 2025Jun 2026Jun 2032⚠ Ending Jun 2026
3.4.xNov 2024Dec 2025Dec 2026🛑 OSS Ended
3.3.xMay 2024Jun 2025Jun 2026🛑 OSS Ended
3.2.xNov 2023Dec 2024Dec 2025🛑 Fully EOL
2.7.xMay 2022Jun 2023Jun 2029🛑 OSS Ended 3 years ago

⚠ If you're still on Boot 2.7 or 3.2…

You are running on a version with no free security patches. Every new CVE discovered in Spring Framework, Spring Security, or any transitive dependency (Jackson, Hibernate, Tomcat, Netty) will not be backported to your version. You are exposed until you upgrade — and the exposure grows with every passing month.

The Six Forces Pulling You Toward Upgrade

🔓

Security Vulnerabilities

Unsupported versions receive zero security patches. Spring Security alone had 14 CVEs in 2024–2025. Each one affects authentication, authorization, and session management — the core of your API security. Running unpatched means every new advisory is an open door.

📋

Compliance & Audit Risk

SOC 2, ISO 27001, PCI-DSS, and internal audit policies require software to be on vendor-supported versions. Running EOL frameworks is an automatic finding in security audits. The longer you wait, the harder it is to explain to auditors why your production services run on unsupported software.

🧩

Dependency Compatibility

Modern libraries drop support for old Spring versions. Jackson 3.0 changed its groupId. Hibernate 7 requires Jakarta EE. Micrometer 2.x restructured its API. Every month you delay, the gap between your deps and the ecosystem widens — and the upgrade gets harder, not easier.

Java Version Support

Spring Boot 4.0 requires Java 17+ and recommends Java 21+. Boot 2.7 can't run on anything above Java 17 reliably. Staying on old Boot versions locks you out of Java 21/25 performance gains: virtual threads, pattern matching, sealed classes, ZGC improvements, and 20-30% better throughput.

📈

Performance & Observability

Boot 4.0 ships with native OpenTelemetry support, replacing the manual Micrometer+OTel wiring. New virtual thread auto-configuration dramatically improves throughput for IO-bound services. GraalVM native image support is production-ready. None of these are backported to older versions.

💰

Cost of Delay

Every major version you skip doubles the upgrade effort. Going from 2.7 → 3.x requires javax → jakarta migration, security DSL rewrite, and starter renames. Going 2.7 → 4.0 adds Jackson 3.0 changes, testing overhaul, and observability restructuring on top. The compound cost is real — and this agent eliminates it.

"The next baseline isn't a destination — it's a continuous capability.
The only question is whether you invest days per quarter doing it manually,
or let the agent engineer it for you in 12 minutes."

Overview
Six Steps, Zero Guesswork

Every upgrade follows the same disciplined process — collect, research, reason, validate, fix, test.

🔍

Collect Every Fact

Parses pom.xml (XML DOM), build.gradle (including libs.versions.toml + Kotlin DSL), application.yml, and every .java file. Runs mvn dependency:tree to capture transitives. Scans for legacy spring.factories vs. modern AutoConfiguration.imports.

📰

Research All 51 Documents

Fetches 42 release notes from GitHub API, 9 migration wiki guides, and the full OpenRewrite recipe catalog (Boot 2.0–4.0). Prioritizes and trims to the LLM context budget.

🧠

AI-Grounded Reasoning

The LLM compares your repo inventory + dependency tree + auto-config state against all release notes. Findings are grounded in YOUR code. Supports OpenAI, Azure OpenAI, and Anthropic Claude.

10-Strategy Validation

Cross-checks every LLM finding against real code, pom deps, plugins, properties, config keys, regex patterns, Java version, and repo URLs. Hallucinations filtered. Only evidence-backed findings survive.

🔧

Automated Fixes

OpenRewrite for deterministic transforms. DOM-based PomVersionUpdater bumps parent, BOM imports, properties. LLM Code Fixer iteratively repairs compile errors with Resilience4j retry and SHA-256 caching.

🧪

Test Stub Generation

Creates JUnit 5 test classes for coverage gaps — actuator contracts, OTLP observability, Jackson serialization round-trips, JWT auth after Security upgrades.

Hallucination Defense
Six Layers of Truth

LLMs hallucinate. We built six independent defenses. Every finding must survive all six before reaching your report.

🌳

Dependency Tree Grounding

DependencyTreeCollector runs mvn dependency:tree with a 90-second timeout. Captures the full resolved classpath — transitive deps, BOM-managed versions, Hibernate pins — things the LLM would otherwise guess about.

⚙️

AutoConfig Scanner

AutoConfigScanner detects legacy spring.factories vs. modern AutoConfiguration.imports. Projects shipping legacy factories on Boot 3+ get a ⚠ warning injected into the LLM prompt.

🛡️

10-Strategy Validator

FindingValidator applies 10 independent checks: exact code match, substring, pom deps/plugins/properties, config keys, subsection blast radius, regex, strict Java version ID, repo URLs. 14 unit tests guard every strategy.

🔄

Resilience4j Retry + Cache

AbstractLlmClient wraps every API call with exponential backoff retry (1s → 2s → 4s, 3 attempts). Responses are SHA-256 cached on disk. Markdown fence stripping cleans raw LLM output before JSON parsing.

📄

Structured Output Schemas

OpenAI calls use response_format.json_schema. Anthropic calls use forced tool_use schema on emit_structured_response. No more hoping the LLM returns valid JSON.

🎯

Strategy 9 — Fixed

Previously, any finding mentioning "java" was auto-confirmed. Now Strategy 9 only matches strict Java version IDs (e.g., java-version-21). Eliminated an entire class of false positives.

Architecture
How the System Flows

Watch data flow from your repo to a production-ready PR. Click any node to explore it.

⚡ Trigger PR · Cron · Manual 📂 Your Repo pom · gradle · java · yml 🌳 Dep Tree Transitive GAVs (90s) 📰 Release Intel 51 documents 🔍 Collect 📰 Research 🧠 Analyze Validate 🔧 Fix 🧪 Test SB Upgrade Agent — Java 25 · 2 Modules · 21 Classes · Resilience4j 🔀 PR Fixes + Tests 📋 Issue 7-section report 📊 Report Markdown file 🖥️ Dashboard Fleet visibility 🧠 LLM Provider OpenAI · Azure · Claude · Retry 🔄 OpenRewrite Boot 2.0→4.0 recipes 📦 Maven Central Versions + dep tree 📡 GitHub API Releases · Wiki · PRs INPUTS PIPELINE OUTPUTS EXTERNAL SERVICES
Pipeline
Step-by-Step Flow

Click any step to expand implementation details.

0Detect Project Type
Checks for pom.xml or build.gradle. Multi-module aware.
If no build file → exits code 0. Supports Maven (XML DOM) and Gradle (regex + version catalogs + Kotlin DSL). Multi-module: walks all child modules.
1Collect Repo Facts
5 collectors scan every aspect of the repository
BuildFileParser — SB version, deps, plugins. Gradle: parses libs.versions.toml, Kotlin DSL, platform().

ConfigParser — Profile-aware YAML. Per-profile separation.

CodeScanner — Multi-module findSourceRoots().

DependencyTreeCollectorNEW. mvn dependency:tree, 90s timeout, 150-line cap.

AutoConfigScannerNEW. spring.factories vs AutoConfiguration.imports.
2Fetch Release Intelligence
51 documents — release notes, wiki, recipes (Boot 2.0–4.0)
GitHub API → 42 GA notes. Wiki → 9 guides (version path via LAST_MINOR_PER_MAJOR). OpenRewrite → expanded Boot 2.0–4.0 catalog. Merged, trimmed.
3LLM AnalysisAI + Grounded
Structured JSON, grounded with dependency tree + auto-config
Prompt includes: RepoFacts + DependencyTree + AutoConfig warnings + ReleaseNotes + Recipes.

Schema: OpenAI json_schema, Anthropic tool_use.

Resilience: Retry 3× exponential. SHA-256 cache. Markdown fence strip.

Providers: OpenAI, Azure OpenAI, Anthropic Claude.
4Validate Findings
10 strategies cross-check against code, POM, and config
1. Code exact 2. Substring 3. Pom deps 4. Plugins 5. Properties
6. Config keys 7. Blast radius 8. Regex 9. Strict Java version ID 10. Repo URLs

Result: CONFIRMED · LIKELY · FILTERED

14 unit tests guard all strategies.
5Generate Report & Deliver
7-section report with properly escaped JSON
Sections: Summary · Breaking Changes · Actions · Risk · OpenRewrite · Test Gaps · Plan

JSON: ObjectMapper.writeValueAsString (control-char safe).

Delivery: GitHub Issue · Markdown file · Dashboard API POST
0Bump Versions (DOM-based)Maven
PomVersionUpdater: DOM rewrite for parent, BOM imports, properties, child poms
DOM-based PomVersionUpdater replaced the old sed-based approach. Handles parent, BOM imports, properties, and child poms.
1Bump DependenciesMaven
mvn versions:update-properties + use-latest-releases
Queries Maven Central for latest GA. Bumps all *.version properties + inline deps. Skips snapshots/milestones/RCs.
2OpenRewrite Auto-FixDeterministic
Expanded recipe catalog — Boot 2.0 through 4.0
MockBean→MockitoBean, starter renames, config property renames, test annotations, AutoConfigurePackages migration.

Catalog now covers Boot 2.0–4.0 (was 3.4/3.5/4.0 only).
3LLM Code FixerAI + Retry
Iterative compile-error repair with multi-line error parsing
Multi-line error accumulator (fixed). Read error → LLM fix → recompile → repeat (3 iterations, 15 files/iter). Tightened /generated/ heuristic. Resilience4j retry + SHA-256 cache.
4Generate Test StubsAI-Generated
JUnit 5 test classes for coverage gaps
ActuatorContractUpgradeTest · OtlpObservabilityTest · JacksonCompatibilityTest · JwtAuthUpgradeTest

Written to src/test/java/.../generated/
5Create Pull Request
git branch → commit → push → gh pr create
Branch: spring-boot-upgrade/auto-fix-YYYYMMDDHHMMSS
PR body lists all phases with ✅/⚠️ labels. Uses gh pr create + GITHUB_TOKEN.
Components
Agent Internals

21 Java classes across 2 modules — sb-upgrade-core (library) and sb-upgrade-cli (fat JAR).

🎯

Agent.java

CLI entry point. Orchestrates the 6-step pipeline. Wires LlmClient, collectors, scanners.

CLIsb-upgrade-cli
📋

BuildFileParser

pom.xml (DOM) + build.gradle (regex + libs.versions.toml + Kotlin DSL). Multi-module.

TOMLKotlin DSL
⚙️

ConfigParser

Profile-aware YAML/properties. Per-profile separation. Secrets redacted.

SnakeYAMLProfiles
🔎

CodeScanner

Multi-module. findSourceRoots() walks all src dirs. Records imports, annotations, patterns.

java.nioMulti-module
🌳

DependencyTreeCollector

NEW. mvn dependency:tree. Dedups by group:artifact. 150-line cap. 90s timeout.

NEWGrounding
⚙️

AutoConfigScanner

NEW. Legacy spring.factories vs. modern AutoConfiguration.imports. Depth-4 walk.

NEWAuto-config
📰

ReleaseNotesFetcher

GitHub API + Wiki clone. Version path via LAST_MINOR_PER_MAJOR map.

HttpClientFixed C6
🔄

OpenRewriteRecipeFetcher

Expanded catalog: Boot 2.0→4.0. buildMavenCommand handles 2.x.

OpenRewriteFixed C5
🧠

LlmClient Abstraction

NEW. Interface + AbstractLlmClient (retry + cache + fence strip). OpenAi + Anthropic implementations.

Resilience4jSHA-256
🧠

LlmAnalyzer

Builds prompt with grounding snippet (dep tree + auto-config). Schema-enforced JSON response.

GroundedSchema

FindingValidator

10 strategies. Strategy 9 fixed. 14 unit tests cover all strategies.

14 testsFixed C3
📊

OutputHandler

JSON via ObjectMapper.writeValueAsString. Issue search via readTree. Control-char safe.

Fixed E1JSON-safe
📝

PomVersionUpdater

Rewritten. DOM-based. Parent + BOM imports + properties + child poms.

DOMRewritten
🔧

LlmCodeFixer

Multi-line error accumulator. Tightened /generated/ heuristic. Resilience4j retry.

Fixed E3Retry
🧪

TestGenerator

JUnit 5 stubs for coverage gaps. LlmClient with retry + cache.

JUnit 5Boot 4
Data Models
Java Records

Immutable data records flowing through the pipeline.

RecordPurposeKey Fields
ProjectDescriptorBuild factssbVersion, javaVersion, dependencies[], plugins[], properties
ConfigFactsConfig (profile-aware)allProperties, actuator, kafka, datasource, security, profiles
CodeFactsCode inventoryinventory Map, importSummary, annotationSummary
DependencyNodeDep tree entrycoordinates (GAV), depth
AutoConfigFactsAuto-config statelegacyFactories[], modernImports[], hasLegacyFactoriesFile
ReleaseIntelligenceRelease notesversionPath, mergedContent, releaseNotes[]
UpgradeAnalysisLLM responseriskLevel, findings[], upgradePlan[], testGaps[]
ValidatedAnalysisPost-validationfindings[] (CONFIRMED/LIKELY), evidence
ChatRequestLLM requestsystemPrompt, userPrompt, model, temperature
AgentConfigRuntime configrepoPath, targetVersion, outputModes, apiKeys
Connections
External Systems

Every external system the agent communicates with.

🧠 LLM Providers
  • Azure OpenAI (structured output)
  • Direct OpenAI (json_schema)
  • Anthropic Claude (tool_use)
  • Resilience4j retry: 1s → 2s → 4s
  • SHA-256 disk cache per run
📡 GitHub API
  • GET releases (42 notes)
  • POST/PATCH issues
  • POST issue comments
  • git push + gh pr create
  • Auth: GITHUB_TOKEN
📚 GitHub Wiki
  • git clone (depth=1)
  • 9 asciidoc guides
  • LAST_MINOR_PER_MAJOR path
📦 Maven Central
  • versions:update-parent
  • versions:update-properties
  • versions:use-latest-releases
  • dependency:tree (grounding)
🔄 OpenRewrite
  • rewrite-maven-plugin:run
  • Boot 2.0–4.0 catalog
  • Deterministic transforms
🖥️ Dashboard
  • POST /api/v1/scans
  • X-API-Key auth
  • Spring Boot 3.5 + PostgreSQL
  • React + Vite frontend
Workflow
GitHub Actions Configuration

Trigger matrix and required secrets.

Trigger Matrix

TriggerJob 1 (Analysis)Job 2 (Auto-Fix)
PR with pom.xml change✅ Creates Issue⏭ Skipped
Weekly cron (Mon 2AM)✅ Creates Issue✅ Creates PR
Manual + auto-fix=false✅ Creates Issue⏭ Skipped
Manual + auto-fix=true✅ Creates Issue✅ Creates PR

Required Secrets

SecretSourcePurpose
AGENT_PATPersonal Access TokenClone private agent repo
OPENAI_API_KEYAzure / OpenAI / AnthropicLLM API access
AZURE_OPENAI_ENDPOINTAzure PortalResource URL
AZURE_OPENAI_DEPLOYMENTAzure PortalModel deployment
AZURE_OPENAI_API_VERSIONAzure PortalAPI version
GITHUB_TOKENAutomaticPRs, Issues, push
Stack
Technology

Everything that powers the agent, dashboard, and CI/CD.

🐳

Agent Runtime

Java 25 CLI. 2-module Maven build. Fat JAR via Shade. Docker: eclipse-temurin:25-jre-alpine.

Java 25Maven 3.9Docker
📦

Dependencies

Jackson 2.18.3, SnakeYAML 2.4, SLF4J 2.0.16, Logback 1.5.16, Resilience4j 2.4.0. Test: JUnit 5.11.4 + AssertJ 3.27.3.

Resilience4jJacksonJUnit 5
🧠

AI / LLM

Multi-provider: Azure OpenAI, direct OpenAI, Anthropic Claude. Structured output per provider. No Spring AI (too heavy).

OpenAIAnthropicSchema
🖥️

Dashboard

Spring Boot 3.5 + JDBC + PostgreSQL (API). React + Vite + TypeScript + Tailwind + Recharts (UI).

Spring Boot 3.5React
🔄

Code Transforms

OpenRewrite (Boot 2.0–4.0). Maven versions plugin. DOM-based PomVersionUpdater.

OpenRewriteDOM

CI/CD

GitHub Actions. Docker-based Action. PAT for private repos. gh CLI for PRs.

GitHub ActionsDocker