Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Automatisierte Migrationen und Refactorings mit...

Automatisierte Migrationen und Refactorings mit OpenRewrite | JUGM 05/2026

Viele von uns kennen die Herausforderung, die das Aktualisieren größerer Codebases mit sich bringt. Insbesondere das Aktualisieren von Frameworks oder Bibliotheken kostet viel Zeit, die mit der Weiterentwicklung von Features oder Behebung von Bugs konkurriert.
OpenRewrite ist ein Open Source Projekt, das genau solche Upgrades und Migrationen automatisiert umsetzen kann. In meinem Vortrag möchte ich mit euch konkret in das Projekt einsteigen. Ich zeige euch unter anderem, wie OpenRewrite unter der Haube funktioniert, und wie ihr selbst Rezepte erstellen und in euren Organisationen verteilen könnt. Selbstverständlich machen wir auch eine live-Migration.

Avatar for Johannes Jank

Johannes Jank

May 14, 2026

More Decks by Johannes Jank

Other Decks in Programming

Transcript

  1. Johannes Jank | Java User Group München | 11.05.2026 Automatisierte

    Migrationen und Refactorings mit OpenRewrite
  2. Häufige Gründe für Software-Migrationen: 1. Sicherheit oder Compliance 2. Performance-Verbesserungen

    3. Produktivitätsgewinn 4. … Oft keine wertschöpfenden Gründe für Unternehmen - eher ein ein notwendiges Übel ¯\_(ツ)_/¯ Upgrades und Migrationen – why bother?
  3. • Spring Boot 2.x → 3.x → 4.x • javax

    → jakarta • Jackson 2 → Jackson 3 • Java 8 → Java 11 → Java 17 → Java 25 • Logj4 → Slf4j (Log4Shell) • Firmen-interne Libraries • Kubernetes Manifeste • … Upgrades und Migrationen – konkrete Beispiele
  4. Wem kommt so etwas bekannt vor? One or more dependencies

    were identified with known vulnerabilities in $application: LatencyUtils-2.0.3.jar (pkg:maven/org.latencyutils/[email protected], cpe:2.3:a:utils_project:utils:2.0.3:*:*:*:*:*:*:*) : CVE-2021-4277 // mehr Zeilen… cpe:2.3:a:apache_tomcat:apache_tomcat:9.0.46:*:*:*:*:*:*:*) : CVE-2021-33037, CVE-2021-42340, CVE-2021- 43980 // …endlich: See the dependency-check report for more details. Dependency-Scanner
  5. • Linter oder statische Analysetools erstellen nur Reports • Viele

    Reports… • …und dann? • Reports und Vorschläge alleine lösen keine Probleme • Automatische Dependency Upgrades a la Dependabot sind ein Schritt in die richtige Richtung, aber noch nicht gut genug Nur Reports – wenig Actions
  6. Wir erinnern uns an diese Metrik: • Nur ein beliebiges

    Beispiel für ein Repository – das Problem wird viel schlimmer “at scale” • Es muss nicht Netflix-Style Scale sein – auch kleinere und mittlere Firmen haben viel Code • Wir alle führen unabhängig voneinander die exakt gleichen Migrationen (Spring Boot 4.x, Jackson 3.x) durch • …Automatisierung? Wir brauchen bessere Tools
  7. • Open-Source Projekt - https://github.com/openrewrite • Ursprünge bei Netflix: Ablösung

    eines internen Logging-Frameworks durch Slf4j • Perfekte Transformation war notwendig • Sollte minimale Änderungen produzieren • Lösung: AST- (Abstract Syntax Tree) Parser und Manipulator, implementiert in Java • Der Gründer Jonathan Schnéider hat um OpenRewrite die Firma Moderne gegründet – die: • Primär die Entwicklung auf Github vorantreibt • Ein SaaS Business rund um OpenRewrite anbietet Enter OpenRewrite
  8. Der Kern von OpenRewrite ist und wird unter Apache 2.0

    lizensiert sein und bleiben • Module mit signifikatem Community Anteil (z.B. rewrite-jackson) => Apache 2.0 • Module mit signifikantem Anteil durch Moderne & Community => Moderne Source Available License • ”In other words, you can't take these recipes and sell them to others and you can't provide consulting/professional services where you charge people and run these recipes.” • “if you work at a company and you want to run these recipes on your own code you are free to do so” • Module, die auschließlich von Moderne gepflegt werden: Moderne Proprietary License Lizenzen
  9. Aus den FAQs: Q: “Can end users and individual companies

    use source available recipes on private code?” A: Yes. Recipes are available to individual users and companies to consume and apply on their own code both under the Apache License Version 2.0 License and the Moderne Source Available License Relevante Links: • Licensing FAQs • Übersicht aller Module inkl. Lizenz Lizenzen
  10. Früher Fokus auf Java und die JVM (Sprachen, Build-Tools, etc)

    • Support für mehr Sprachen (Javascript, Python und C#) ist wird zur Zeit entwickelt – ist aber noch nicht so ausgereift • Schon heute gibt es viele Recipes - die Grundbausteine von OpenRewrite • Ausführung durch Maven- oder Gradle-Plugins Was ist unterstützt
  11. Ein Auszug aus https://docs.openrewrite.org/recipes Der Recipe catalog A screenshot of

    a computer AI-generated content may be incorrect. A screenshot of a computer AI-generated content may be incorrect.
  12. • Der von OpenRewrite aufgebaute AST hat mehr Informationen als

    ein “gewöhnlicher” AST • OpenRewrite nennt diese Datenstruktur einen Losless Semantic Tree (LST) • Enthält exakte und vollständige Typinformationen • Kennt spezifische Formattierung • Azyklisch – kann serialisiert werden Recipes under the hood – Lossles Semantic Trees Quelle: https://docs.openrewrite.org/concepts-and-explanations/lst-examples
  13. • Recipes manipulieren den LST und schreiben die Veränderungen zurück

    in die betroffenen Files • Werden mit dem Visitor Pattern implementiert: • Code finden (match) • ggf. Ersetzten (modifiy) • Konkretes Beispiel: Add @AutoConfigureTestRestTemplate if necessary • Hintergrund: TestRestTemplate ist in Spring Boot 4 in @SpringBootTest Klassen nicht mehr by-default als Bean verfügbar und muss durch @AutoConfigureTestRestTemplate aktiviert werden Recipes under the hood
  14. Die gute Nachricht: Oft wird man keinen eigenen Visitor implementieren

    müssen • Recipes sind composable - viele kleine Schritte ergeben zusammen eine (große) Migration • Dieser Ansatz ist deklarativ – die Recipes werden als YAML-Files geschrieben und so auch verteilt • In einem Jar sucht OpenRewrite unter /META-INF/rewrite/ nach YAML Recipes Eigene Recipes
  15. Yaml Recipes - Spring Boot 4.0 type: specs.openrewrite.org/v1beta/recipe name: org.openrewrite.java.spring.boot4.UpgradeSpringBoot_4_0

    displayName: Migrate to Spring Boot 4 description: ‘Migrate applications to the latest Spring Boot 4.0 release.’ tags: - spring - boot type: specs.openrewrite.org/v1beta/recipe name: org.openrewrite.java.spring.boot4.UpgradeSpringBoot_4_0 displayName: Migrate to Spring Boot 4 description: ‘Migrate applications to the latest Spring Boot 4.0 release.’ tags: - spring - boot recipeList: - org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_5 - org.openrewrite.java.spring.framework.UpgradeSpringFramework_7_0 - org.openrewrite.java.spring.security7.UpgradeSpringSecurity_7_0 - org.openrewrite.java.spring.batch.SpringBatch5To6Migration - org.openrewrite.java.spring.boot4.SpringBootProperties_4_0 - org.openrewrite.java.spring.boot4.ReplaceMockBeanAndSpyBean - org.openrewrite.hibernate.MigrateToHibernate71 - org.openrewrite.java.testing.testcontainers.Testcontainers2Migration - org.openrewrite.java.springdoc.UpgradeSpringDoc_3_0 - org.openrewrite.java.spring.boot4.MigrateToModularStarters type: specs.openrewrite.org/v1beta/recipe name: org.openrewrite.java.spring.boot4.UpgradeSpringBoot_4_0 displayName: Migrate to Spring Boot 4 description: ‘Migrate applications to the latest Spring Boot 4.0 release.’ tags: - spring - boot recipeList: - org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_5 - org.openrewrite.java.spring.framework.UpgradeSpringFramework_7_0 - org.openrewrite.java.spring.security7.UpgradeSpringSecurity_7_0 - org.openrewrite.java.spring.batch.SpringBatch5To6Migration - org.openrewrite.java.spring.boot4.SpringBootProperties_4_0 - org.openrewrite.java.spring.boot4.ReplaceMockBeanAndSpyBean - org.openrewrite.hibernate.MigrateToHibernate71 - org.openrewrite.java.testing.testcontainers.Testcontainers2Migration - org.openrewrite.java.springdoc.UpgradeSpringDoc_3_0 - org.openrewrite.java.spring.boot4.MigrateToModularStarters - org.openrewrite.java.dependencies.UpgradeDependencyVersion: groupId: org.springframework.boot artifactId: "*" newVersion: 4.0.x overrideManagedVersion: false type: specs.openrewrite.org/v1beta/recipe name: org.openrewrite.java.spring.boot4.UpgradeSpringBoot_4_0 displayName: Migrate to Spring Boot 4 description: ‘Migrate applications to the latest Spring Boot 4.0 release.’ tags: - spring - boot recipeList: - org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_5 - org.openrewrite.java.spring.framework.UpgradeSpringFramework_7_0 - org.openrewrite.java.spring.security7.UpgradeSpringSecurity_7_0 - org.openrewrite.java.spring.batch.SpringBatch5To6Migration - org.openrewrite.java.spring.boot4.SpringBootProperties_4_0 - org.openrewrite.java.spring.boot4.ReplaceMockBeanAndSpyBean - org.openrewrite.hibernate.MigrateToHibernate71 - org.openrewrite.java.testing.testcontainers.Testcontainers2Migration - org.openrewrite.java.springdoc.UpgradeSpringDoc_3_0 - org.openrewrite.java.spring.boot4.MigrateToModularStarters - org.openrewrite.java.dependencies.UpgradeDependencyVersion: groupId: org.springframework.boot artifactId: "*” <- Wildcards newVersion: 4.0.x overrideManagedVersion: false type: specs.openrewrite.org/v1beta/recipe name: org.openrewrite.java.spring.boot4.UpgradeSpringBoot_4_0 displayName: Migrate to Spring Boot 4 description: ‘Migrate applications to the latest Spring Boot 4.0 release.’ tags: - spring - boot recipeList: - org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_5 - org.openrewrite.java.spring.framework.UpgradeSpringFramework_7_0 - org.openrewrite.java.spring.security7.UpgradeSpringSecurity_7_0 - org.openrewrite.java.spring.batch.SpringBatch5To6Migration - org.openrewrite.java.spring.boot4.SpringBootProperties_4_0 - org.openrewrite.java.spring.boot4.ReplaceMockBeanAndSpyBean - org.openrewrite.hibernate.MigrateToHibernate71 - org.openrewrite.java.testing.testcontainers.Testcontainers2Migration - org.openrewrite.java.springdoc.UpgradeSpringDoc_3_0 - org.openrewrite.java.spring.boot4.MigrateToModularStarters - org.openrewrite.java.dependencies.UpgradeDependencyVersion: groupId: org.springframework.boot artifactId: "*” <- Wildcards newVersion: 4.0.x <- Semantic versioning overrideManagedVersion: false
  16. “Wir haben hier eine Anwendung aus bestehend ~30 Microservices. Die

    sind alle noch auf Boot 1.5.x und müssen dringend aktualisiert werden…” Mit vergleichbaren Aufgaben sind einige von uns vermutlich schon konfrontiert worden • Da kommt einiges an Arbeit zusammen: • Spring Boot 1.x auf 2.x • Deployment Descriptoren • diverse andere Konfiguration • Properties, die via Spring Cloud Configserver bezogen werden • … • Bei ~1 Tag pro Service (nur für Code- und Konfigration) ~30 Tage Arbeit Case Study einer Migration (angepasst)
  17. OpenRewrite to the rescue type: specs.openrewrite.org/v1beta/recipe name: com.acme.migrate.SomeMigration recipeList: #

    Tomcat statt Jetty - org.openrewrite.maven.RemoveDependency: groupId: org.springframework.boot artifactId: spring-boot-starter-jetty # Log4J entfernen - org.openrewrite.maven.RemoveDependency: groupId: org.springframework.boot artifactId: spring-boot-starter-log4j - org.openrewrite.DeleteSourceFiles: filePattern: src/main/resources/log4j.properties # Elastic Logback Appender - org.openrewrite.maven.AddMavenDependency: groupId: co.elastic.logging artifactId: logback-ecs-encoder version: latest - org.openrewrite.text.CreateTextFile: relativeFileName: src/main/resources/logback-spring.xml fileContents: '<?xml version="1.0" encoding="UTF-8"?> <configuration> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="co.elastic.logging.logback.EcsEncoder" /> </appender> <root level="INFO"> <appender-ref ref="STDOUT" /> </root> </configuration>' - org.openrewrite.properties.AddProperty: property: spring.application.name value: $$CHANGE-ME$$ <-- Custom visitor…? fileMatcher: src/main/resources/application.properties # Zu guter letzt: Spring Boot 2.x - org.openrewrite.java.spring.boot2.UpgradeSpringBoot_2_7
  18. Die Verteilung ist im Java-Umfeld sehr einfach: • Deklarative YAML

    Recipes unter /META-INF/rewrite/ • Custom Code – eigene Visitors - wie bei jedem anderen Jar • Jar ins firmeneigene Maven Repository publizieren • Konsumenten können solche Jars dann als Abhängigkeit bei der Migration angeben (vgl. Demo): mvn org.openrewrite.maven:rewrite-maven-plugin:run \ -Drewrite.recipeArtifactCoordinates=com.acme.migrate:rewrite-custom:1.0.0 \ -DactiveRecipes=com.acme.migrate.SomeMigration Recipes verteilen
  19. • POC erfolgreich: • Wenige Minuten Ausführungszeit pro Repository •

    Keine Gefahr von Copy & Paste-Fehlern • Mehr Zeit um die Migration inhaltlich zu verifizieren – Semantik > Syntax Erfahrungen aus Proof-of-Concept
  20. • Konsistent AssertJ in allen Tests? • Kein Problem Migrate

    Hamcrest assertions to AssertJ • Best practises für • Java • Maven • Spring Boot • ... • Eigene Patterns, die in eurem Kontext sinnvoll sind und angewendet werden sollten • Composability von Recipes => Mix & Match Nicht nur Migrations – auch Code Style und Konsistenz
  21. Thoughtworks Technology Radar Vol. 33 (November 2025) Techniques - 6.

    AI for code migrations: Trial “Code migrations take many forms […] and are rarely trivial, often requiring months of manual effort. […] In the past, we blipped OpenRewrite, a deterministic, rule-based refactoring tool. Using AI alone for such upgrades has often proven costly and prone to meandering conversations. Instead, the team combined traditional upgrade pipelines with agentic coding assistants to manage complex transitions. This hybrid approach positions AI coding agents as pragmatic collaborators in software maintenance. Industry examples, such as Google’s large-scale int32-to-int64 migration, reflect a similar trend. While our results are mixed in measurable time savings, the potential to reduce developer toil is clear and worth continued exploration.” Wie passt AI hier ins Bild?
  22. OpenRewrite hat sich in den letzten Jahren weiter verbreitet (Thoughtworks

    Tech Radar Vol 32, April 2025) “OpenRewrite continues to serve us well as a tool for large-scale refactorings that follow a set of rules […]. Support for languages beyond Java, notably JavaScript, has been introduced. With short LTS release cycles in frameworks like Angular, keeping projects updated to newer versions has become increasingly important. Wünschenswert: Library- und Framework-Entwickler liefern bei Updates selbst die Recipes mit aus Ausblick
  23. Egal ob ”legacy” oder frisches Cloud native Projekt – Updates

    kommen immer • Mit OpenRewrite bleibt mehr Zeit für die wesentlichen Dinge: • Fachlichkeit • Architektur • Kommunikation • …alles, was glückliche User oder Kunden bringt Fazit
  24. Call to Action: Probiert OpenRewrite aus und werdet Teil der

    Community • Offizielle Dokumentation: • Recipe catalog • Running recipes – getting started • Writing a Java refactoring recipe • Concepts and explanations • Authoring recipes • OpenRewrite Slack - die Leute dort sind unfassbar schnell und hilfsbereit • Live Trainings vom OpenRewrite Team • YouTube-Channel mit vielen hilfreichen Deep dives und Q&A’s • Code auf Github Next Steps
  25. Senior Technical Consultant Johannes Jank bbv Software Services GmbH Elsenheimerstr.

    9 80687 München Email: [email protected] LinkedIn: Johannes Jank Github: jjank Speakerdeck: jjank Telefon: +49 89 452 4383 43 Kontakt