Java 版本升级是企业技术债务里排名前三的难题。不是说改个版本号的事——依赖兼容性分析、框架 Breaking Change 处理、命名空间迁移、构建工具适配、回归测试……每一步都可能翻车。一个项目手动升两周,五十个项目排到年底都搞不完。
亚马逊云科技推出的 AWS Transform Custom 用了一个比较有意思的思路——用 Agentic AI 来自动化这个流程。我详细看了它的技术架构和工作机制,结合 Spring PetClinic 的实际升级过程,分析一下这个方案的设计逻辑。
一、问题域分析
1.1 Java 升级的复杂度模型
一个典型的企业 Java 项目升级,复杂度来自四个维度:
依赖图的不确定性。Maven/Gradle 项目的依赖是一棵树(实际上是 DAG),直接依赖可能有几十个,传递依赖可能有几百个。JDK 版本变化时,这棵树上的任何节点都可能出问题。Java 17 移除了 javax.* 包(JEP 320),这意味着所有还在使用旧命名空间的库都需要找到兼容版本。
框架级 API 断裂。Spring Boot 2.x 到 3.x 是个经典案例。这次升级强制要求从 javax 迁移到 jakarta 命名空间(Jakarta EE 9 规范),影响范围覆盖 JPA、Servlet、Validation、WebSocket 等。Spring Security 的配置方式也有较大变化(WebSecurityConfigurerAdapter 被废弃)。
构建工具链适配。不只是源代码,Maven 插件、Gradle 插件也需要同步升级。比如 maven-compiler-plugin 的老版本可能不认 Java 17 的 class file version(61.0),maven-surefire-plugin 需要升级才能正确处理 Java 17 的 module system。
测试覆盖的信心缺口。代码改了,怎么知道没改坏?测试覆盖率低的老项目,这个问题尤其严重。
1.2 传统方案的局限
传统的 Java 升级方案有两种:
- 手动升级:人工分析依赖、逐个修改、反复试错。质量取决于工程师的经验和耐心。
- 工具辅助(如 OpenRewrite):基于规则的静态代码转换,能处理已知模式(如 javax→jakarta 的包名替换),但遇到规则库未覆盖的场景就无能为力。
两种方案的共同问题是不能闭环——修改代码之后需要手动验证构建和测试结果,发现问题再手动修,形成"改→试→报错→再改"的循环。
二、Transform Custom 的架构设计
2.1 Agentic AI 的升级流程
AWS Transform Custom 采用了 Agent 化的设计,把升级过程拆成 8 个阶段:
确认要求 → 粗读代码 → 制定计划 → 全面 Review → 修改计划 → 执行升级 → 测试验证 → 生成报告
关键的架构决策有两个:
闭环执行:Agent 在"执行升级"阶段,每改一步都会调用构建命令(如 ./mvnw package)验证结果。如果构建失败,Agent 分析错误信息,自动修复后重新构建。这解决了传统方案"改和验分离"的问题。
增量 Commit:每步执行成功后自动 git commit,形成清晰的变更历史。如果后续步骤出问题,可以精确回滚到特定步骤。
2.2 两种使用模式
- 交互模式(Interactive):通过
atxCLI 工具启动对话式会话,适合单个项目的精细化升级。开发者可以实时看到 Agent 的分析过程,在关键节点做决策。 - 非交互模式(Non-Interactive):通过命令行参数驱动,适合批量场景。可以集成到 CI/CD 流水线,遍历仓库列表批量执行。
2.3 支持的转换类型
| 转换类型 | 示例 |
|---|---|
| 语言版本升级 | Java 8→17/21, Python 3.9→3.13, Node.js 12→22 |
| 框架升级 | Spring Boot 2.x→3.x, React 17→18 |
| API 迁移 | AWS SDK v1→v2, JUnit 4→5 |
| 命名空间迁移 | javax→jakarta |
2.4 与 Kiro 的定位差异
| 维度 | Kiro | Transform Custom |
|---|---|---|
| 产品性质 | 通用 AI 编程助手 | 专项代码转换服务 |
| 适用规模 | 单文件或小范围精细操作 | 跨项目批量系统性转换 |
| 交互模式 | 实时对话协作 | 预定义规则批量自动执行 |
| 执行特点 | 交互式、渐进式 | 自动化、批量化 |
| 适用场景 | 日常开发:写功能/调试/重构 | 技术债清理:版本升级/框架迁移 |
简单说,Kiro 是通用外科医生,Transform Custom 是流水线式的专科手术室。一个处理个案,一个处理批量。
三、实战:Spring PetClinic 升级过程
3.1 环境与目标
- 源版本:Java 8 + Spring Boot 2.x
- 目标版本:Java 17 + Spring Boot 3.x
- 项目:Spring PetClinic(spring-projects/spring-petclinic,efficient-webjars 分支)
- 环境:Amazon Linux 2023 ARM64
3.2 准备工作
# 安装 Node.js 20+
curl -fsSL https://rpm.nodesource.com/setup_20.x | sudo bash -
sudo dnf install -y nodejs# 安装 atx CLI
curl -fsSL https://transform-cli.awsstatic.com/install.sh | bash
atx --version# 拉取项目
git clone https://github.com/spring-projects/spring-petclinic.git
cd spring-petclinic
git checkout efficient-webjars
3.3 执行过程
atx
> 请将这个 Java 8 + Spring Boot 2.x 项目升级到 Java 17 + Spring Boot 3.x
> 构建命令:./mvnw package
Agent 的执行路径大致如下:
- 扫描阶段:识别出 Maven 项目结构、Spring Boot 2.x parent、Spring Data JPA、Thymeleaf、H2 Database 等依赖
- 计划阶段:输出升级清单——pom.xml 版本号变更、javax→jakarta 替换列表、插件升级列表
- 执行阶段:逐项执行变更,每步跑构建验证:
- Step 1:修改
pom.xml中 Java 版本(1.8→17)和 Spring Boot parent 版本 - Step 2:替换所有
javax.*import 为jakarta.* - Step 3:升级 Maven 插件版本
- Step 4:调整配置文件和注解
- Step 1:修改
- 报告阶段:输出完整变更日志
3.4 技术细节观察
javax → jakarta 的范围:不只是 javax.persistence,还包括 javax.servlet、javax.validation、javax.annotation。Agent 做了全量扫描,没有遗漏。
Maven 插件兼容:maven-compiler-plugin、maven-surefire-plugin 等需要升级到支持 Java 17 class file version 的版本。这个如果人工搞,需要逐个查文档确认兼容版本。
测试代码同步升级:JUnit 的 import 路径、Spring Test 的注解变化也一并处理了。
四、批量升级方案
对于拥有几十个微服务的企业,Transform Custom 的批量模式是关键价值点:
- 定义转换规则(如"Java 8→17 + Spring Boot 2→3")
- 准备仓库列表
- 非交互模式批量执行,每个仓库独立跑
- 收集升级报告
- 人工 Review 关键变更,合并 PR
这种方式把"N 个项目 × 人工升级时间"的线性成本,变成了"N 个项目 × AI 执行时间 + 人工 Review 时间"。AI 执行时间远小于人工升级时间,Review 时间也比从零开始升级短得多。
五、局限性与建议
Transform Custom 能做的:机械性的版本升级、依赖替换、命名空间迁移、配置文件调整。
Transform Custom 不做的:业务逻辑变更、架构重构、性能优化。这些需要人的业务判断。
实操建议:
- 先用 Spring PetClinic 练手,验证流程
- 正式项目在独立分支上跑,Review 后再合并
- 确保测试覆盖率达到可接受水平再升级
- 批量升级分批次推进(先 5 个,再 20 个,再全量)
参考资源:
- AWS Transform 文档
- Transform Custom 常见用例
- Spring PetClinic 项目
