Posts Tagged ‘OpenRewrite’
[SpringIO2026] Hybrid Modernization: Combining OpenRewrite’s Precision with LLM Intelligence for Spring
Lecturer
Raquel Pau is a technical product manager at Broadcom (formerly VMware Tanzu). She brings extensive experience in Java developer tools, continuous-integration and continuous-delivery platforms, and internal developer platforms. Previously she worked as an engineering manager at Moderne, the company behind OpenRewrite, and held product-management roles at CloudBees focused on developer productivity. She has spoken at multiple Spring I/O editions as well as Devoxx, JavaConf and JavaZone. Her background combines deep technical knowledge of code-transformation tooling with product thinking about how large organizations can keep their application portfolios modern and consistent.
Abstract
Code modernization is not a single problem. Upgrading a Spring Boot application within the same major version, migrating from JAX-RS to Spring MVC, and rewriting a COBOL batch job into Spring Batch demand fundamentally different strategies. This article explores the taxonomy of modernization tasks proposed by Raquel Pau and the hybrid methodology that pairs OpenRewrite’s deterministic, type-aware recipes with the semantic reasoning power of large language models. Concrete demonstrations illustrate how upgrade plans are calculated from Maven metadata, how skills orchestrate recipe execution followed by LLM-driven semantic fixes, and how a structured DSL extracted from legacy code guides a full rewrite while preserving contracts and enabling incremental delivery.
Deterministic versus Non-Deterministic Transformations
Modernization tools fall into two broad categories. Deterministic tools always produce the identical output for a given input. Renaming a method, updating a package import, or replacing a deprecated Spring API are deterministic operations. OpenRewrite belongs to this category: it operates on a lossless semantic tree that retains type attribution obtained from the compiler, applies visitor-based recipes, and preserves the original formatting of the source. Because the transformation is deterministic, recipes can be unit-tested with high confidence and executed at scale across hundreds of repositories without surprise.
Non-deterministic problems admit many correct answers. Generating documentation, extracting the business intent of a filter, or inventing an idiomatic Spring Security configuration from a set of JAX-RS name-binding annotations are examples. Large language models excel here because they reason over patterns and can synthesize higher-level constructs that do not exist in the original code. The cost, however, is variability, the need for evaluation harnesses, and a tendency to hallucinate when internal libraries or proprietary APIs are outside the model’s training distribution.
OpenRewrite’s limitations are the mirror image of its strengths. It cannot perform runtime analysis; dependency injection and reflection mean that many object relationships become visible only after the application starts. It cannot invent new semantic abstractions; a mechanical translation of JAX-RS filters into Spring filters often leaves residual compilation errors or suboptimal configurations that require human or LLM insight. Cross-language migration is outside its design scope.
Coding agents partially compensate for these gaps by using pattern-based reasoning and by iterating until the project compiles. Yet they lack default type attribution, suffer from context-window constraints, and generate large volumes of tokens before reaching a stable state. The rational strategy is therefore hybrid: apply deterministic recipes first to shrink the problem, then invoke the LLM only for the residual semantic work.
Three Levels of Modernization
Pau organizes modernization into three progressively more demanding levels.
Upgrades remain inside the same framework family. A Spring Boot 3.3 application is moved to Spring Boot 4, simultaneously updating transitive dependencies such as Jackson and JUnit. Because Spring’s release train is not strictly linear and because organizations maintain internal frameworks with their own release cadences, a simple “latest version” recipe is insufficient. An upgrade-plan engine inspects Maven metadata, calculates a sequence of compatible intermediate steps, and emits a series of small, reviewable pull requests. Each step leaves the application in a buildable state. Tanzu’s Application Advisor exposes this capability via the cf repo upgrade plan and cf repo apply upgrade plan commands, demonstrating that continuous, low-risk upgrades can be embedded in CI pipelines.
Migrations change the underlying framework while preserving language and runtime. The canonical example is Jakarta JAX-RS to Spring Boot. Name-binding annotations that attach filters to resources have no direct counterpart; authentication filters must become Spring Security configurations; repositories must acquire @Repository annotations. The recommended skill therefore first executes the OpenRewrite recipes that perform the mechanical rewrite and any accompanying Spring Boot upgrade, then hands control to the coding agent to resolve remaining compilation errors and to map name-binding semantics onto Spring constructs. The result is both more complete and far less expensive in tokens than asking an unconstrained LLM to rewrite the entire application.
Full rewrites discard the original implementation while preserving contracts. A COBOL batch program that sorts records by date and amount must become a Spring Batch job that reads the same input format, produces identical output, and respects the same database schema if one is involved. Because legacy systems rarely possess comprehensive tests, the process begins by extracting a catalog of user stories, then a structured domain-specific language description of inputs, outputs, and processing steps. Only after the human reviewer validates the generated tests and the semantic model does the agent emit Spring code, typically seeded by a skeleton obtained from start.spring.io. Incremental delivery is essential: large monolithic rewrites cannot be reviewed or risk-managed in a single step.
Orchestrating OpenRewrite and LLM Agents
Three integration mechanisms allow a coding agent to invoke OpenRewrite without saturating its context window. Local MCP servers expose the rewrite CLI so that only the command and its concise output enter the conversation. Skills package the same CLI invocation and are loaded only when the agent decides the skill is relevant. Prompts can be registered with a remote MCP server, yet they must be fully present in every conversation and therefore scale poorly for complex migrations.
The hybrid skill for a JAX-RS migration therefore looks roughly as follows: calculate the upgrade plan that includes the JAX-RS recipes, execute the recipes, collect residual compilation diagnostics, and finally apply semantic transformations that replace name-binding filters with Spring Security and Spring MVC constructs. Because the deterministic phase has already performed the bulk of the mechanical work, the LLM operates on a far smaller residual problem and produces higher-quality results.
For full rewrites the skill is organized into three explicit phases. Phase one extracts a user-story catalog and stores it under version control so that subsequent runs reuse the analysis. Phase two materializes a structured DSL for a chosen story, including acceptance criteria, data models, and external contracts. Phase three generates the Spring implementation and correlating tests. Human validation remains mandatory; the agent cannot be trusted to invent missing requirements or to decide whether an original implementation was correct.
Practical Demonstrations and Organizational Implications
In the upgrade demonstration a Spring Petclinic application on Boot 3.3 is analyzed; the engine proposes coordinated upgrades of Spring Boot, Jackson and JUnit; successive apply steps produce small, reviewable diffs that leave the project green after each commit. In the migration demonstration a pure JAX-RS Petclinic is transformed: OpenRewrite rewrites the bulk of the code, the agent resolves compilation issues caused by signature changes, and name-binding annotations disappear in favor of proper Spring Security configuration. In the rewrite demonstration a simple COBOL sorter is analyzed, a single user story and its DSL are generated, a Spring Batch project is scaffolded, and the resulting executable produces byte-for-byte identical output.
The organizational payoff is standardization. When every application can be moved to a common Spring Boot baseline with low friction, teams share libraries, security configurations and operational practices. Token consumption drops dramatically because deterministic recipes eliminate the majority of mechanical work. Evaluation of non-deterministic skills becomes feasible because the residual problem set is smaller and more homogeneous.
Conclusion
Modernization success depends on matching the tool to the nature of the transformation. OpenRewrite supplies precision, testability and scalability for deterministic changes. Large language models supply the semantic insight required for migrations and rewrites. A carefully designed hybrid that keeps the LLM outside the hot path of routine upgrades, that constrains its context to residual problems, and that forces explicit contracts for full rewrites yields both higher quality and lower cost. Organizations that adopt this disciplined approach can keep large application portfolios current without sacrificing reviewability or operational safety.
Links:
[MiamiJUG] Taming Vulnerabilities and Technical Debt Through Deterministic Refactoring
Lecturer
Kevin Brockhoff is a Director and Consulting Expert at CGI, one of the world’s largest IT and business consulting firms. With decades of experience in the technology industry, Kevin specializes in navigating the complex intersections of cybersecurity, digital transformation, and large-scale enterprise systems. His work at CGI involves helping multinational organizations—spanning sectors such as banking, government, and manufacturing—modernize their legacy infrastructure while maintaining robust security postures. Kevin is a prominent voice in the Miami technology community, frequently sharing insights at the Miami Java User Group (MiamiJUG) regarding automated refactoring and the integration of generative AI in software engineering.
Abstract
As enterprises face an accelerating stream of feature requests and increasingly sophisticated cyber threats, the accumulation of technical debt and security vulnerabilities has become a critical bottleneck. This article examines a deterministic approach to large-scale code remediation using OpenRewrite, an open-source automated refactoring ecosystem. Unlike indeterminate generative AI agents, which can produce inconsistent results and hallucinations, OpenRewrite utilizes Lossless Semantic Trees (LSTs) to ensure predictable, traceable, and scalable code transformations. By combining the creative potential of AI with the reliability of rule-based transformers, organizations can achieve a fourfold increase in productivity for vulnerability remediation. The following analysis explores the methodology of LST-based refactoring, its application across thousands of repositories, and its strategic role in modernizing global IT infrastructure.
The Crisis of Speed and Indeterminacy in Enterprise Software
In the modern software landscape, engineering teams are caught in a perpetual race between delivering new features and mitigating emerging security risks. Kevin emphasizes that speed is the decisive factor in this environment; delays in remediation allow vulnerabilities to proliferate across growing application portfolios. While generative AI agents have been proposed as a solution to this problem, they introduce significant challenges when applied in isolation at an enterprise scale.
The primary issue with relying solely on Large Language Models (LLMs) for code refactoring is their indeterminate nature. Applying an AI agent to the same codebase multiple times may yield different results, and the risk of “hallucinations” necessitates a manual human review of every line of code. Furthermore, current AI tools often struggle with scalability; while they may function effectively on a single repository, managing transformations across 5,000 repositories requires a more structured, traceable mechanism.
OpenRewrite: Deterministic Refactoring via Lossless Semantic Trees
To address the limitations of AI, Kevin advocates for the use of OpenRewrite, a tool sponsored by Moderne that provides a deterministic framework for source code modification. At the heart of OpenRewrite is the Lossless Semantic Tree (LST). While a traditional Abstract Syntax Tree (AST) represents the hierarchical structure of code, the LST incorporates two additional layers of critical information:
- Type Information: Every node in the tree is enriched with comprehensive type data, similar to the output of a compiler.
- Formatting Preservation: Uniquely, the LST captures all original formatting, including whitespace and comments.
This architecture allows OpenRewrite to parse code, apply transformations, and write it back to the source file with character-for-character fidelity to the original style, provided no changes were intended. Most importantly, these modifications are deterministic; a “recipe”—the rule-based transformer used by the engine—will produce identical results every time it is applied, enabling mass application across thousands of repositories without the need for exhaustive manual re-verification.
Methodology: Combining AI with Rule-Based Transformers
The most effective strategy for large-scale remediation involves a hybrid approach that leverages both AI and deterministic tools. In this model, AI agents are used to assist human developers in generating the refactoring recipes themselves. Once a recipe is refined and tested, it acts as a reliable, version-controlled asset that can be executed at scale.
OpenRewrite’s ecosystem is divided into open-source and commercial components. The core engine and a vast catalog of common recipes—covering framework migrations (such as Spring Boot upgrades), security fixes, and stylistic consistency—are available under the Apache license. For large-scale enterprise management, the Moderne platform provides advanced capabilities, including:
- SaaS and On-Premise (DX) Options: These allow for mass refactoring across an entire organization’s source code system.
- Semantic Search: By calculating embeddings on LSTs, the platform enables highly sophisticated code intelligence and search.
- Batch Remediation Tracking: A centralized dashboard for managing the progress of large-scale security and tech debt campaigns.
Implementation and Impact
The practical application of these tools has demonstrated a 4X increase in productivity for security vulnerability remediation at major corporations. Beyond security, use cases include technical modernization, library upgrades, and maintaining architectural standards. By automating the “grunt work” of refactoring, senior engineers can focus on higher-level architectural decisions while the deterministic engine ensures that thousands of microservices remain up-to-date with the latest security patches and framework versions.
Relevant links and hashtags:
[SpringIO2022] Major Migrations Made Easy with OpenRewrite
Tim te Beek’s Spring I/O 2022 session introduced OpenRewrite, a powerful tool for automating large-scale Java migrations. As a Java consultant at JDriven, Tim shared his passion for updating outdated technology stacks, using OpenRewrite to streamline upgrades across frameworks, libraries, and languages. His talk, delivered on his birthday, combined a compelling narrative with a live demo, showcasing how OpenRewrite transforms tedious migrations into quick, safe operations.
The Migration Challenge: Keeping Up with Open Source
Tim opened with a decade-long perspective on Java and Spring evolution, from Spring Framework 2.5 in 2009 to Java 17 and Spring Boot 2 in 2022. Each release—Java 8’s lambdas, Spring Boot’s reduced boilerplate, JUnit 5, or Java 11’s JAX-B dependencies—introduced valuable features but required manual upgrades across multiple services. Vulnerabilities like Log4Shell further necessitate rapid migrations, often under pressure. For large organizations with thousands of services, manual updates are impractical, making automation essential.
OpenRewrite addresses this by leveraging an abstract syntax tree (AST) to perform precise, safe refactorings. Unlike simple search-and-replace, it understands code context, preserving formatting and ensuring functional integrity. Tim emphasized its ability to handle migrations like JUnit 4 to 5, Log4j to SLF4J, or Spring Boot 1 to 2, reducing technical debt in minutes.
How OpenRewrite Works: Recipes and AST Magic
OpenRewrite’s core strength lies in its recipe-based approach. Recipes are modular, reusable transformations—implemented as Java visitors—that modify the AST. Tim explained how recipes range from simple (changing imports) to complex (converting JUnit 4’s expected exceptions to JUnit 5’s assertThrows). These can be combined into modules for tasks like framework upgrades or style enforcement. The tool supports Java, Groovy, YAML, and XML, enabling changes to Maven/Gradle builds and Spring configurations.
A key differentiator is OpenRewrite’s type attribution and format preservation, ensuring changes blend seamlessly with existing code. Tim’s demo illustrated this by migrating a Spring Pet Clinic project from Spring Boot 1.5 (Java 8) to Spring Boot 2.5 (Java 17). Using Maven’s OpenRewrite plugin, he applied recipes to update dependencies, imports, annotations, and properties, completing the migration in under 15 seconds per step, with only two minor test failures requiring manual fixes.
Spring Boot Migrator: Enhancing OpenRewrite
Tim introduced Spring Boot Migrator, an experimental Spring project built on OpenRewrite, designed to simplify migrations to Spring Boot. Initiated by VMware Labs in 2020 and led by Fabian Krüger, it offers an opinionated API for Spring-specific migrations, such as Java EE to Spring or NetWeaver to Spring Integration. Unlike OpenRewrite’s fully automated recipes, Spring Boot Migrator provides an interactive workflow, generating HTML reports to guide developers through component identification and transformation steps.
Looking ahead, Spring Boot Migrator aims to support Spring Framework 6 and Spring Boot 3, expected in November 2022, and facilitate cloud migrations to GraalVM. Tim encouraged community contributions, noting its role in easing enterprise migrations for VMware customers.
Impact and Community: Scaling Automation
OpenRewrite’s open-source model, backed by Moderne, ensures all recipes are Apache-licensed, fostering community-driven development. Tim highlighted its use in fixing static analysis issues (e.g., Checkstyle, Sonar), enforcing code style, and contributing to open-source projects like WireMock and Apache Maven. He shared his experience migrating thousands of unit tests, urging attendees to explore OpenRewrite’s web interface (app.moderne.io) and contribute recipes.
Tim’s talk inspired developers to embrace automation, reducing migration pain and enabling focus on innovation. His enthusiasm for OpenRewrite’s potential to transform development workflows resonated strongly with the audience.