官方更新 AWS ML Blog Thu, 29 Oct 2026 正文 ok 2281 words

使用 Kiro 构建可复用的 PHP 到 Java 迁移引擎

英文标题:Build a repeatable PHP-to-Java migration engine with Kiro

本文介绍了如何借助 AI IDE Kiro 将高风险的 PHP 到 Java 迁移转变为可度量、可复用的工程化流程。该方案依托“先发现后翻译”理念、轻量化发现扫描器以及“对齐优先(Parity-first)”的八阶段工作流,把原有 PHP 系统视作系统规范,并通过一致性测试套件严格裁判生成的 Spring Boot 代码。此外,该引擎支持开发者交互式(Kiro)与大规模自主式(AWS Transform)双重执行路径,贯彻“修改规则循环而非手动修补代码”的核心原则,为大型遗留系统的现代化改造提供了高可靠的自动化范式。
打开原文相关 1.8 · 机会 2
media1.3 MB media1.3 MB media2.4 KB media345.0 KB media141.2 KB media346.5 KB media64.8 KB media129.6 KB media58.2 KB media47.8 KB media64.6 KB media25.1 KB media18.9 KB media23.4 KB media128.0 KB

中文

当团队将成熟的 PHP 应用程序迁移至 Java 时,能够获得更强的类型安全性、更广泛的类库支持以及更具可预测性的扩展能力。然而,使用 Laravel、Symfony 或 Doctrine 历经多年构建的 PHP 代码库,其业务规则往往隐藏在并不显眼的地方(例如 Eloquent traits 或是 XML 映射文件)。因此,即便结构相似的 Java 移植版本可以顺利编译,其实际运行行为仍可能大相径庭。

本文将展示如何借助 Kiro,将 PHP 到 Java 的迁移从一场“全凭运气的冒险”转变为一个可度量、可复用的流程。Kiro 是一款 AI 集成开发环境(IDE),它将 AI Agent 与你的代码库深度绑定,在开发者实时参与(developer-in-the-loop)的情况下执行多步骤工程任务。该方案的核心是一个可复用的引擎:包括一套共享方法论、一个机械化发现扫描器以及一个八阶段工作流。该引擎将原始 PHP 应用程序视为唯一规格说明书,在一致性校验套件(parity harness)验证通过之前,坚决不盲目判定 Java 移植版本正确。

前提条件

在开始之前,你需要准备:

  • 熟悉 PHP(Laravel/Eloquent 或 Symfony/Doctrine)。掌握 Java 知识(Spring Boot、JPA)有助于审查生成的代码,不过引擎会自动生成符合习惯的 Java 代码,因此无需自行手动重写。
  • 一个具有 Skills 和 Steering 文件访问权限的 Kiro 工作区。
  • 运行发现扫描器的机器需安装 PHP 8.0 或更高版本,生成的 Spring Boot 项目需配备 Java 21 与 Maven。
  • 对迁移规划(发现、转译与验证)具备基础了解。

本文你将学到什么

我们将从一个开源代码仓库开始,方便你亲自运行该引擎而不仅仅是阅读文章。该引擎所掌握的所有知识都沉淀在一组精简的 skill 文件中;借助这些文件,你可以以多种方式执行同一套方法论。

运行引擎的两种方式:Kiro 与 AWS Transform

这里的一切都被封装为 skill 文件:即对迁移方法论(php-to-java-migration)与发现扫描器工作流(php-model-discovery)进行编码的版本化 Markdown 能力包。由于这些知识沉淀在文件中而非依赖某个特定工具,因此你可以通过两种方式运行同一套方法论。

方式 1:Kiro,交互式且有开发者参与

Kiro 将 AI Agent 引入编辑器中,逐步推进迁移。将代码仓库根目录作为 Kiro 工作区打开,当你要求 Kiro 迁移 PHP 应用时,相关技能将自动激活。随后,Kiro 会沿着设置了明确审批关卡的八阶段工作流推进:你可以在下一阶段开始前审查发现清单、批准规则手册(rulebook)并完成阶段验收。本文中的每个示例都基于此模式。

方式 2:AWS Transform,Agentic 自主化与跨项目组合规模

AWS Transform 是 AWS 面向大规模迁移与现代化改造的 Agentic AI 服务,目前已与 Kiro 实现原生集成。通过该集成,你可以向 AWS Transform 交付指导 Kiro 交互式会话的同一组 skill 文件,从而将“先发现后翻译”、“一致性套件充当裁判”以及“修改循环机制,而非手工修改代码”等准则直接应用于全自动运行中。

各自适用的场景

  • 控制权与自主性: 先使用 Kiro 梳理代码:在单个应用上运行 skill,审查生成的 Java 代码并执行测试。当你准备迁移更多项目时,让 AWS Transform 以 Agentic 方式运行相同的方法论,并在 skill 定义的检查点进行人工审查。
  • 规模与新框架探索: Kiro 每次处理一个应用程序,适合处理此前未涉足的首创型框架。AWS Transform 则可将多个应用作为并行作业批量处理。
  • 共享反馈回路: 两种路径读取相同的 skill 文件,因此在 Kiro 中对规则手册所做的每一次修复,都会让下一次 AWS Transform 运行受益,反之亦然。

方案概览:一套共享大脑,支撑多个项目

该引擎围绕单一原则组织:一套共享大脑,支撑多个项目。要打开它,请先在本地克隆代码仓库,然后在 Kiro 中打开文件夹并选择仓库根目录(包含 .kiro/ 的目录)。Kiro 会自动加载 skills 和 steering,更详细的步骤见“入门指南”。

工作区将共享方法论层与使用它的各个项目隔离开来,如下图所示。顶部是所有项目共享的全局 .kiro/ 层。其下方是各个独立项目文件夹,每个项目都包含各自的 PHP 源码、Java 输出以及规范子文件夹。

工作区架构:一套共享大脑,支撑多个项目。工作区布局图。顶部是 Kiro 工作区根目录 PHP-Java-Migration。其下方是 .kiro/ 下的共享全局层,存放 skills(方法论)和 steering 文件(指导工作流),适用于每个项目。再往下是三个项目独立文件夹,每个都包含各自的 spec 子文件夹,图表指出只需改进一次共享层即可惠及所有项目。

图 1:工作区被划分为共享全局方法论层以及各项目专用的代码和规范文件夹

这些相同的共享 skill 文件可以通过两种不同的方式运行,如下图所示。相同的八阶段“对齐优先”流水线既可以由 Kiro 驱动(交互式,一次一个应用),也可以由 AWS Transform 驱动(Agentic 自主化,面向应用组合级规模),两者都能将 PHP 源码转换为经过对齐验证的 Spring Boot Java 代码。

PHP 到 Java 迁移引擎:一套共享大脑,两条执行路径。迁移引擎概览。左侧的共享层包含每个项目都会使用的 skill 文件和 steering 文件。右侧的两条执行路径运行相同的方法论:Kiro 负责单应用交互式处理,AWS Transform 负责面向项目组合的 Agentic 处理。其下方是一条八阶段流水线,从 PHP 代码库开始,经历阶段 0 到 3(人类判断),随后是阶段 4 到 8(自驱循环),最终收敛于充当裁判的一致性校验套件。

图 2:相同的共享 skill 文件驱动两条执行路径:Kiro(交互式,单应用)和 AWS Transform(Agentic,规模化)。两者运行完全相同的八阶段对齐优先流水线,将 PHP 源码转为经过对齐验证的 Spring Boot Java 代码

.kiro/ 下的全局共享层包含两个 Skills:php-model-discovery(扫描器)与 php-to-java-migration(八阶段操作手册),以及 core-workflow.md Steering 文件。每个独立项目文件夹都包含自身的 PHP 源码、Java 输出以及 .kiro/specs/ 下的规范子文件夹。因此,对方法论层进行的单次改进,便可让所有项目直接继承收益。

转译之前,先做发现

最关键的第一条准则必须在做任何事之前执行:在扫描器运行完成之前,切勿直接阅读、主观推测或手动转译任何模型或实体文件。

扫描器以单次遍历方式运行且无任何外部依赖,如下图所示。它对源码 Token 应用三种发现策略,并输出一份单一的 JSON 清单;任何存在歧义的内容都会被路由到待人工复核的 review-flag 队列中。

php-model-discovery,三种策略,一份清单。发现扫描器 discover-models.php 示意图。左侧 PHP 代码库输入扫描器,扫描器依次运行三种策略:Eloquent 模型发现、Doctrine 注解检测和 ORM XML 映射。随后箭头将结果输出至右侧的 model-manifest.json,其中包含字段、类型转换和关系的 models 数组,以及作为人工复核队列的 flags 数组。

图 3:扫描器在源码 Token 上运行三种发现策略,并生成包含人工复核标记队列的单一 JSON 清单

扫描器是 discover-models.php,一个单文件、零依赖的 PHP 命令行工具,它不会执行目标代码。由于它仅将源码文本解析为 Token,因此无论目标应用是否已安装依赖,均可直接运行。它在每次扫描时运行三项策略:Eloquent 模型发现(沿类继承链追溯至 Illuminate\Database\Eloquent\Model)、Doctrine 注解检测(检测 #[ORM\Entity] 属性)以及 ORM XML 映射(解析外部 *.orm.xml 文件)。输出结果是一份单一的 JSON 清单。其中的 models[] 数组包含所有字段、类型转换(cast)、关系和可见性规则,并且每个条目都会附带一个 flags[] 数组。扫描器会标记歧义而非胡乱推测。例如,由运行时表达式动态构建的 $fillable 列表会被转换为通俗的人类可读标记,该标记列表便构成了人工复核队列。

对齐优先流水线

阶段 0 是准备阶段:运行扫描器并汇总资产清单。接下来的前三个阶段集中体现人类专家的判断。阶段 1 在编写任何 Java 代码之前构建一致性校验套件(parity harness),对 PHP 原版和 Java 移植版重放请求/响应对。该套件必须能够在正常运行的 PHP 上测试通过,且在你故意注入破坏时报错——因为一个漏报人为注入故障的测试套件是不值得信任的。阶段 2 生成规则手册和差距清单初始化种子(RULEBOOK.md、GAP_INVENTORY.md),阶段 3 则在代表性文件上对其进行压力测试,确认稳固后再推广至整个应用程序。

对齐优先迁移流水线(8 个阶段)。包含 8 个阶段的对齐优先迁移流水线示意图。阶段 0 到 3 是人工主导的决策步骤,阶段 4 到 8 是自驱循环,两部分共同输入给作为裁判的一致性套件,对比 PHP 原版与 Java 移植版。

图 4:人类判断被前置于准备阶段 0 及阶段 1–3。阶段 4–8 主要是自驱循环,由一致性校验套件充当裁判

前四个阶段集中凝聚了人类专业知识。阶段 0 运行扫描器并整理出清单。阶段 1 在编写 Java 代码之前构建一致性套件,针对 PHP 原版和 Java 移植版重放请求/响应对。测试套件必须在正常运行的 PHP 上通过,并在人为引入破坏时报错,因为未能捕获注入损坏的测试套件无法令人信服。阶段 2 生成规则手册和差距清单种子(RULEBOOK.md、GAP_INVENTORY.md),阶段 3 在代表性文件上进行压力测试,之后再在全应用范围内推开。

阶段 名称 交付物
0 评估与发现 模型清单 + 资产清单 + 切流方案选择
1 构建评判器 可针对 PHP 和 Java 运行的一致性校验套件
2 规则手册 + 差距清单 RULEBOOK.md、GAP_INVENTORY.md
3 规则手册压力测试 强化后的规则手册,经过代表性文件验证
4 项目脚手架 可编译的 Spring Boot 项目
5 转译数据模型 JPA 实体 + Schema 基线
6 转译 I/O 层 控制器、安全配置与模板响应正常
7 转换业务逻辑 逻辑完成转换,测试全部通过(Green)
8 证明对齐与正式切流 一致性校验报告 + 切流检查清单

阶段 4–8 主要是自驱循环:阶段 4 构建项目脚手架,阶段 5 基于清单转译数据模型,阶段 6 转译 I/O 层(路由转为控制器,中间件转为过滤器,验证规则转为带注解的数据传输对象 DTO),阶段 7 分批转换业务逻辑,阶段 8 通过测试套件验证一致性并执行切流。该循环由两条原则主导:第一,PHP 代码即规格说明书——移植工作仅在裁判认可或所有不匹配均被记录为批准变更时方告完成;第二,修改循环机制,而非手工修改代码——遇到问题应修订规则手册并重新生成,而非手动打补丁。

实战演练:从 Eloquent 到 Spring Boot

laravel-eloquent-sample 项目是一个切实可运行、边界明确的示例:它是某个开源 Laravel 应用的只读切片,包含 Book、Chapter、Page 和 User 模型,已被迁移至基于 Java 21、Maven 和内存数据库 H2 的 Spring Boot 3.4.1 体系中。

从 PHP 到 Spring Boot 的映射是机械化且可追溯的,如下图所示。左侧的每个清单条目都会映射到右侧的 Java 结构中,构成了生成应用切片的分层运行时架构。

从 Eloquent 到 Spring Boot:映射与生成的应用切片。图表分为两部分。左侧将 PHP 和 Laravel Eloquent 结构映射到其对应的 Java 和 Spring Boot 等效项,带有指示配对关系的箭头(如模型映射为 JPA 实体,查询作用域映射为 Spring Data Repository 方法)。右侧显示生成的 book-stack 切片的分层架构:HTTP 客户端调用控制器层,控制器层调用仓库层,随后是实体层,最后连接到 H2 内存数据库。

图 5:左侧为清单驱动的映射关系。右侧为生成的应用切片的分层运行时架构

这些映射是机械化且完全可追溯至清单的:PHP 命名空间转换为 Java 包,Eloquent 模型转换为 JPA @Entity,hasMany 与

English / 原文

When your team moves a mature PHP application to Java, you gain stronger type safety, broader library support, and more predictable scaling. A PHP codebase built over the years with Laravel, Symfony, or Doctrine carries business rules in places that are not obvious, from Eloquent traits to XML mapping files, so a structurally similar Java port can compile cleanly and still behave differently.

This post shows how to turn PHP-to-Java migration from a one-time leap of faith into a measurable, repeatable process using Kiro. Kiro is an AI integrated development environment (IDE) that pairs an AI agent with your codebase to run multi-step engineering tasks with you in the loop. The approach centers on a reusable engine: a shared methodology, a mechanical discovery scanner, and an eight-phase workflow. This engine treats the original PHP application as the specification and refuses to declare the Java port correct until a parity harness verifies it.

Prerequisites

Before getting started, you need:

  • Familiarity with PHP (Laravel/Eloquent or Symfony/Doctrine). Java knowledge (Spring Boot, JPA) helps you review the generated output, but the engine produces idiomatic Java for you, so you don’t need to rewrite the application in Java yourself.
  • A Kiro workspace with access to Skills and Steering files.
  • PHP 8.0 or newer on the machine running the discovery scanner, and Java 21 with Maven for the generated Spring Boot projects.
  • A basic understanding of migration planning (discovery, translation, and validation).

What you will learn in this post

You start with an open repository, so you can run the engine yourself rather than read about it. Everything the engine knows lives in a small set of skill files, and with those files, you can run the same methodology in more than one way.

Two ways to run the engine: Kiro and AWS Transform

Everything here is packaged as skill files: versioned Markdown capability packages that encode the migration methodology (php-to-java-migration) and the discovery scanner workflow (php-model-discovery). Because that knowledge lives in files rather than any one tool, you can run the same methodology in two ways.

Method 1: Kiro, interactive and developer-in-the-loop

Kiro brings an AI agent into your editor to drive a migration step by step. Open the repository root as a Kiro workspace and the skills activate automatically when you ask Kiro to migrate a PHP application. Kiro then walks the eight-phase workflow with explicit approval gates, so you review the discovery manifest, approve the rulebook, and sign off on each phase before the next begins. It’s the mode used for every example in this post.

Method 2: AWS Transform, agentic and at portfolio scale

AWS Transform is the AWS agentic AI service for large-scale migration and modernization, and it now integrates natively with Kiro. Through that integration, you can hand AWS Transform the same skill files that govern an interactive Kiro session, so discovery before translation, the parity harness as referee, and ‘ fix the loop, not the code ’ apply to an autonomous run.

When each path fits

  • Control and autonomy: Use Kiro to work through the code first: run the skill on one application, read the generated Java, and run the tests. When you want to migrate more, AWS Transform runs the same methodology agentically with review at the checkpoints the skill defines.
  • Scale and novelty: Kiro handles one application at a time and suits first-of-a-kind frameworks. AWS Transform runs many applications as parallel jobs.
  • A shared feedback loop: Both paths read the same skill files, so every rulebook fix made in Kiro improves the next AWS Transform run, and vice versa.

Solution overview: One shared brain, many projects

The engine is organized around a single principle: one shared brain, many projects. To open it, clone the repository locally, then in Kiro open a folder and select the repository root (the folder containing .kiro/). Kiro loads the skills and steering automatically, with fuller steps in “Getting started.”

The workspace separates a shared methodology layer from the individual projects that use it, as shown in the following diagram. At the top is a global .kiro/ layer that every project draws on. Beneath it sit the per-project folders, each with its own PHP source, Java output, and specification sub-folder.

Workspace architecture: one shared brain, many projects. Diagram of the workspace layout. At the top is the Kiro workspace root, PHP-Java-Migration. Below it, a shared, global layer under .kiro/ holds the skills (the methodology) and the steering file (the governing workflow), and applies to every project. Beneath that, three per-project folders each hold their own spec sub-folder, and the diagram notes that improving the shared layer once benefits every project.

Figure 1: The workspace is split into a shared, global methodology layer and per-project code and spec folders

Those same shared skill files can be run in two different ways, shown in the following diagram. The identical eight-phase, parity-first pipeline can be driven either by Kiro (interactive, one application at a time) or by AWS Transform (agentic, at portfolio scale), and both convert PHP source into parity-verified Spring Boot Java.

PHP-to-Java Migration Engine: One Shared Brain, Two Execution Paths. Overview of the migration engine. A shared layer on the left holds the skill files and steering file that every project uses. Two execution paths on the right run the same methodology: Kiro, for interactive work on one application at a time, and AWS Transform, for agentic work across a portfolio. Below them, an eight-phase pipeline runs from the PHP codebase through Phases 0 to 3 (human judgment), then Phases 4 to 8 (self-driving loops), and ends at a parity harness that acts as the referee.

Figure 2: The same shared skill files drive two execution paths: Kiro (interactive, one app at a time) and AWS Transform (agentic, portfolio scale). Both run the identical eight-phase parity-first pipeline, converting PHP source into parity-verified Spring Boot Java

A shared, global layer under .kiro/ holds two Skills, php-model-discovery (the scanner) and php-to-java-migration (the eight-phase playbook), plus the core-workflow.md Steering file. Each per-project folder holds its own PHP source, Java output, and spec sub-folder under .kiro/specs/, so improving the methodology once lets every project inherit the gain.

Discovery before translation

The single most important rule fires before anything else: Don’t read, guess at, or hand-translate a model or entity file until the scanner has run.

The scanner works in a single pass with no dependencies, as shown in the following diagram. It applies three discovery strategies to the source tokens and emits one JSON manifest, with anything ambiguous routed to a review-flag queue for a human to resolve.

php-model-discovery, three strategies, one manifest. Diagram of the discovery scanner, discover-models.php. On the left, the PHP codebase feeds into the scanner, which runs three strategies in sequence: Eloquent model discovery, Doctrine attribute detection, and ORM XML mapping. An arrow then carries the results to model-manifest.json on the right, which holds a models array of fields, casts, and relationships, plus a flags array that serves as the human review queue.

Figure 3: The scanner runs three discovery strategies over source tokens and emits a single JSON manifest with a review-flag queue

The scanner is discover-models.php, a single-file, dependency-free PHP command-line tool that doesn’t execute the target code. It only reads source text as tokens, so it runs against apps of your choice whether its dependencies are installed. It runs three strategies on every scan: Eloquent model discovery (walking the class inheritance chain to Illuminate\Database\Eloquent\Model), Doctrine attribute detection (the #[ORM\Entity] attribute), and ORM XML mapping (external *.orm.xml files). The output is a single JSON manifest. A models[] array carries every field, cast, relationship, and visibility rule, and a flags[] array appears on every entry. The scanner flags ambiguity rather than guessing. For example, a $fillable list built from a runtime expression becomes a plain-English flag, and that flag list is the human review queue.

The parity-first pipeline

Phase 0 is preparatory: it runs the scanner and assembles the inventory. The first three phases then concentrate human expertise. Phase 1 builds the parity harness before Java is written, replaying request/response pairs against both the PHP original and the Java port. The harness must pass against working PHP and fail when you break it deliberately, because a harness that misses injected breakage is not trusted. Phase 2 seeds the rulebook and gap inventory (RULEBOOK.md, GAP_INVENTORY.md), and Phase 3 stress-tests it against representative files before committing it across the application.

The parity-first migration pipeline (8 phases) Diagram of the parity-first migration pipeline with eight phases. Phases 0 to 3 are the human-led judgment steps, and Phases 4 to 8 are self-driving loops, and both groups feed a parity harness that acts as the referee comparing the PHP original with the Java port.

Figure 4: Human judgment is front-loaded into a preparatory Phase 0 and Phases 1–3. Phases 4–8 are mostly self-driving loops, refereed by a parity harness

The first four phases concentrate human expertise. Phase 0 runs the scanner and assembles the inventory. Phase 1 builds the parity harness before Java is written, replaying request/response pairs against both the PHP original and the Java port. The harness must pass against working PHP and fail when you break it deliberately, because a harness that misses injected breakage is not trusted. Phase 2 seeds the rulebook and gap inventory (RULEBOOK.md, GAP_INVENTORY.md), and Phase 3 stress-tests it against representative files before committing it across the application.

Phase Name Deliverable
0 Assess and discover Model manifest + inventory + cutover choice
1 Build the judge Parity harness runnable against PHP and Java
2 Rulebook + gap inventory RULEBOOK.md, GAP_INVENTORY.md
3 Stress-test the rulebook Hardened rulebook, validated against representative files
4 Scaffold Compiling Spring Boot project
5 Translate the data model JPA entities + schema baseline
6 Translate the I/O layer Controllers, security, templates respond
7 Convert business logic Logic converted, tests green
8 Prove parity and cut over Parity report + cutover checklist

Phases 4–8 are mostly self-driving loops: Phase 4 scaffolds the project, Phase 5 translates the data model from the manifest, Phase 6 translates the I/O layer (routes become controllers, middleware becomes filters, validation becomes annotated data transfer objects), Phase 7 converts business logic in batches, and Phase 8 proves parity against the harness and cuts over. Two principles govern the loop. First, the PHP code is the specification: the port is done when the referee agrees, or each mismatch is logged as an approved change. Second, you fix the loop, not the code, amending the rulebook and regenerating rather than hand-patching.

Walkthrough: From Eloquent to Spring Boot

The laravel-eloquent-sample project is a working, bounded example: a read-only slice of an open source Laravel application, with the Book, Chapter, Page, and User models migrated to Spring Boot 3.4.1 on Java 21 with Maven and an in-memory H2 database.

The mapping from PHP to Spring Boot is mechanical and traceable, as shown in the following diagram. Each manifest entry on the left maps to a Java construct on the right, producing the layered runtime architecture of the generated application slice.

From Eloquent to Spring Boot: mapping and the generated slice. Diagram in two parts. The left side maps PHP and Laravel Eloquent constructs to their Java and Spring Boot equivalents, with arrows linking each pair, such as models to JPA entities and query scopes to Spring Data repository methods. The right side shows the layered architecture of the generated book-stack slice: an HTTP client calls a controller layer, which calls a repository layer, then an entity layer, and finally an H2 in-memory database.

Figure 5: Manifest-driven mappings on the left. The layered runtime architecture of the generated application slice on the right

The mappings are mechanical and traceable back to the manifest: a PHP namespace becomes a Java package, an Eloquent model becomes a JPA @Entity, has Many and belongs to relationships become @OneToMany and @ManyToOne, and Eloquent query scopes become Spring Data repository methods. The discipline shows in serialization: html, markdown, and text carry @JsonIgnore because the manifest recorded them in Page’s $hidden list, while Book’s description deliberately doesn’t.

The spec is candid that only 4 of 37 models were ported and, most important, that the parity harness was never built for this slice, which it calls “the single biggest gap.” Documenting where it falls short is itself part of the design.

Getting started

The complete migration engine is available in the sample PHP-to-Java migration repository.

To use it:

  1. Clone the repository and open its root as your Kiro workspace (open a folder and select the folder containing .kiro/). Nothing to install beyond PHP 8.0+ for the scanner and Java 21 with Maven.
  2. Fetch the PHP source into the project’s source-php/ folder. The README pins the exact upstream commits used for parity so anyone can reproduce the baseline.
  3. Ask Kiro to migrate the application. The php-to-java-migration skill activates automatically, runs the scanner first, generates a fresh spec under .kiro/specs/, and walks you through the approval gates.
  4. For an agentic run, point AWS Transform at the same skill files, so its agents execute the identical methodology across your portfolio.

The methodology auto-detects Laravel, Symfony, CodeIgniter, and plain PHP, and extension is additive: add a detection row and a references/<framework>-to-spring.md guide for a new framework. Because Kiro and AWS Transform read the same files, refining them once upgrades both engines.

Clean up

If you deployed the sample Spring Boot application during this walkthrough:

  1. Stop the running Spring Boot application (the in-memory H2 database is ephemeral and requires no separate cleanup).
  2. Remove the generated Java project folder from your workspace if no longer needed.
  3. The discovery scanner produces only a JSON manifest file. Delete the discovery scanner’s JSON manifest from your working directory if you don’t plan to reference it.
  4. No AWS resources are provisioned by the migration engine itself, so there are no cloud resources to deprovision.

Conclusion

We showed how to build a repeatable PHP-to-Java migration engine with Kiro that turns large-scale rewrites into a measurable, compounding process. The key principles are:

  • Discovery before translation: A mechanical scanner inventories every model, field, and relationship, so you don’t guess at structure.
  • Build the judge before the code: A parity harness defines done before the first line of Java is written.
  • Fix the loop, not the code: When the same mistake appears across files, amend the rulebook and regenerate rather than hand-patching.
  • One shared brain: The methodology is written once, shared across projects, and improves with each migration.

None of this is specific to PHP or Java. The same shape applies to other migrations where the old system is the only complete specification. Clone the sample PHP-to-Java migration repository, open it as a Kiro workspace, and explore the Skills and Steering capabilities that power it, or bring the same skill files to AWS Transform. For more about language migration patterns on AWS, see the AWS Prescriptive Guidance documentation.


About the authors

Sarat Guttikonda

Sarat is a Principal Solutions Architect at Amazon Web Services (AWS), where he partners with Strategic Accounts to design and deliver cloud solutions at scale. Passionate about artificial intelligence (AI) and machine learning (ML), he helps customers drive innovation and transformation while preserving business agility. Outside of work, Sarat enjoys playing co-op games on the PS5 with his son, traveling, and playing badminton.

Phani Parcha

Phani is a Senior Technical Account Manager (Strat) at Amazon Web Services with 22+ years of experience in building and scaling enterprise platforms. He drives architecture excellence, system reliability, and operational performance for large-scale enterprise workloads. Phani specializes in distributed systems, microservices architecture, and cloud-native platforms, with a focus on enabling enterprise transformation and Generative AI solutions.

Pallavi Jha

Pallavi is a Technical Consultant at Amazon Web Services, helping customers boost developer productivity through Kiro and the AI-Driven Development Lifecycle (AIDLC). She works with enterprises modernizing their engineering practices, focusing on delivering higher-quality software faster with AI-assisted, spec-driven development. Outside work, she enjoys creating music and hiking.