关于 rpg-migration-analyzer
面向将 AS/400 或 IBM i 上 RPG III/IV/ILE 应用现代化为 Java 的团队的迁移分析技能,可将程序逻辑、数据、文件和依赖映射为迁移方案及报告。
主要功能
- 01解析 RPG 规格与逻辑
- 02将 RPG 数据类型映射到 Java
- 03将文件 I/O 转为 JPA 或 JDBC 模式
- 04分析调用、文件和依赖关系
- 05生成 Java 结构与迁移报告
适用场景
- 01评估 RPG 代码以推进现代化
- 02规划从 AS/400 或 IBM i 迁移到 Java
- 03映射 RPG 文件和数据结构
- 04估算迁移复杂度与工作量
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ dauquangthanh/ hanoi-rainbow --skill rpg-migration-analyzer安装后在 Claude Code 中输入/rpg-migration-analyzer确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/java-class-template.javamigration-report-template.mdreferences/messaging-integration.mdperformance-patterns.mdpseudocode-common-rules.mdpseudocode-rpg-advanced.mdpseudocode-rpg-core-rules.mdpseudocode-rpg-data-structures.mdpseudocode-rpg-functions.mdpseudocode-rpg-migration-guide.mdpseudocode-rpg-patterns.mdpseudocode-rpg-rules.mdpseudocode-rpg-rules.md.backuptesting-strategy.mdtransaction-handling.mdscripts/analyze-dependencies.ps1analyze-dependencies.shestimate-complexity.pyextract-structure.pygenerate-java-classes.py详细介绍
RPG 迁移分析器
分析来自 AS/400 和 IBM i 系统的旧版 RPG 程序(RPG III/IV/ILE),为迁移到现代 Java 应用提取业务逻辑、数据结构、文件操作,并生成可执行的迁移策略。
概述
此技能为 RPG(报表程序生成器)应用提供全面的分析和迁移规划。它提取程序规范,将 RPG 数据类型转换为 Java 等效类型,将文件操作映射到现代数据库访问模式,并生成可直接用于实现的 Java 代码结构。
迁移重点:RPG 到 Java,并妥善处理压缩十进制数(BigDecimal)、数据结构(POJO)、文件操作(JPA/JDBC)、指示符(布尔变量)并保留业务逻辑。
何时使用此技能
在以下情况下使用此技能:
- 分析用于现代化改造的 RPG 源文件(.rpg、.rpgle、.RPGLE)
- 规划从 AS/400 或 IBM i 系统迁移到 Java
- 将 RPG 数据结构(D-specs)转换为 Java 类
- 将 RPG 文件操作(F-specs)映射到数据库访问模式
- 了解 RPG 程序依赖关系和调用链
- 根据 RPG 业务逻辑生成等效 Java 代码
- 估算 RPG 迁移项目的复杂度和工作量
- 创建迁移文档和策略报告
- 将旧版大型机应用现代化为微服务
- 用户提及:RPG 分析、AS/400 迁移、IBM i 现代化、报表程序生成器、压缩十进制数转换
核心功能
1. 程序分析
提取并分析 RPG 程序组件:
- 规范类型:H-spec(标头/控制)、F-spec(文件定义)、D-spec(数据定义)、C-spec(计算/逻辑)、P-spec(过程)
- 数据结构:包含嵌套结构、数组(DIM)、外部引用(EXTNAME)、限定符(LIKEDS、QUALIFIED)的 D-specs
- 文件定义:物理文件、逻辑文件、显示文件(WORKSTN)、打印机文件
- 业务逻辑:计算规范、控制结构(IF/ELSE/DO/FOR)、表达式(EVAL)
- 指示符:旧版指示符(*IN01-*IN99)、内置指示符(*INLR、*INOF)
- 内置函数:字符串函数(%SUBST、%TRIM、%SCAN)、日期函数(%DATE、%DAYS)、数学函数(%DEC、%INT)、文件状态(%EOF、%FOUND、%ERROR)
- 错误处理:%ERROR、%STATUS、ON-ERROR 块
2. 数据结构映射
将 RPG 数据定义转换为 Java 等效类型:
- D-spec 转换:将数据结构定义转换为 Java 类(POJO)
- 数据类型映射:
- 压缩十进制数(P)→
BigDecimal(保留精度) - 分区十进制数(S)→
BigDecimal(带符号的十进制数) - 字符(A)→
String - 日期(D)→
LocalDate - 时间(T)→
LocalTime - 时间戳(Z)→
LocalDateTime - 指示符(N)→
boolean - 二进制整数(I)→
int或long
- 压缩十进制数(P)→
- 数组(DIM):转换为 Java
List<T>或数组T[] - 嵌套数据结构:将 LIKEDS 转换为嵌套 Java 类
- 外部数据结构(EXTNAME):根据数据库表定义生成 JPA 实体
- 初始化(INZ):映射为 Java 字段初始值设定项或构造函数
3. 文件操作
解析并将 RPG 文件 I/O 转换为现代数据库访问方式:
- 文件类型:物理文件(DISK)、逻辑文件(键控访问)、显示文件(WORKSTN)、打印机文件(PRINTER)
- 访问方法:顺序(完整读取)、键控(按键直接访问)、到达顺序
- I/O 操作:
- READ/READE → JPA 查询方法、JDBC ResultSet 迭代
- WRITE → JPA persist()、JDBC INSERT
- UPDATE → JPA merge()、JDBC UPDATE
- DELETE → JPA remove()、JDBC DELETE
- CHAIN → JPA findById()、Optional 模式
- SETLL/READE 循环 → 带排序的 JPA findBy...() 查询
- 文件状态:%EOF(文件结束)、%FOUND(找到记录)、%ERROR(I/O 错误)→ Java 异常或 Optional
- 事务边界:识别提交边界(COMMIT 操作代码)
4. Java 迁移策略
生成现代 Java 实现模式:
- POJO:根据 D-spec 数据结构生成普通 Java 对象
- JPA 实体:为数据库表添加 @Entity 注解(基于 EXTNAME 文件)
- Repository 模式:使用 Spring Data JPA Repository 操作文件
- 服务方法:根据过程和子例程实现业务逻辑
- Bean Validation:根据 RPG 字段验证添加 @NotNull、@Size、@DecimalMin/Max
- 异常处理:将 %ERROR 模式转换为带自定义异常的 try-catch 代码块
- 集合:将 RPG 数组和数据结构转换为 Java Collections API(List、Map、Set)
- DTO:为服务边界创建数据传输对象
- 事务管理:在提交边界添加 @Transactional 注解
5. 依赖分析
映射程序关系和外部依赖:
- 程序调用:CALLB(绑定过程调用)、CALLP(原型过程调用)
- 服务程序:BNDDIR(绑定目录)、*SRVPGM 对象
- 文件依赖:程序访问的所有物理文件/逻辑文件
- 数据库表:引用的 DB2 for i 表(EXTNAME)
- /COPY 成员:包含文件、复制源成员、原型
- 调用链:识别调用程序和被调用程序
- 共享数据区:*DTAARA 的使用情况
- 消息队列:QMHSNDPM(发送程序消息)
说明
按照以下步骤分析并迁移 RPG 程序到 Java:
步骤 1:定位 RPG 源文件
查找 RPG 源文件(RPG III/IV/ILE 自由格式的 .rpg、.rpgle、.RPGLE 扩展名)。
find . -name "*.rpg" -o -name "*.rpgle" -o -name "*.RPGLE"
步骤 2:分析程序结构
提取规范(H、F、D、C、P)、数据结构、文件定义、过程和依赖项。
自动化:运行 scripts/extract-structure.py 自动提取。
步骤 3:映射数据类型
将 RPG 类型转换为 Java 类型——重要:打包/分区十进制数始终使用 BigDecimal(切勿使用 float/double)。
| RPG 类型 | Java 类型 | 重要说明 |
|---|---|---|
nP m(打包) | BigDecimal | 必须保留精度 |
nS m(分区) | BigDecimal | 带符号的十进制数 |
A(字符) | String | 字符数据 |
D/T/Z(日期/时间) | LocalDate/LocalTime/LocalDateTime | 日期字段 |
N(指示符) | boolean | True/False 标记 |
I(整数) | int 或 long | 二进制整数 |
DIM(n)(数组) | List<T> 或 T[] | 数组 |
步骤 4:转换代码模式
将 RPG 操作转换为 Java——主要转换方式:
- 计算:将 EVAL 表达式转换为 BigDecimal 算术方法
- 文件 I/O:将 CHAIN 转换为带 Optional 的
findById(),将 READ 转换为查询方法 - 数组:将 1 基索引(RPG)调整为 0 基索引(Java)
- 字符串:将 %SUBST(1 基索引)转换为 substring(0 基索引)
- 指示符:将 *IN01 转换为具名布尔变量
有关完整的转换模式,请参阅 pseudocode-rpg-rules.md。
步骤 5:生成 Java 实现
创建:
- 根据 D-spec 数据结构生成 POJO(
scripts/generate-java-classes.py) - 为数据库表创建 JPA 实体
- 创建 Repository 接口(Spring Data JPA)
- 为业务逻辑创建服务方法
- 添加异常处理和验证
步骤 6:分析依赖项
映射程序调用(CALLB/CALLP)、文件依赖、/COPY 成员和服务程序。
自动化:运行 scripts/analyze-dependencies.sh 或 .ps1
步骤 7:创建迁移报告
生成包含程序概述、依赖项、数据映射、Java 设计和复杂度估算的文档。
模板:使用 assets/migration-report-template.md
步骤 8:验证和测试
验证:BigDecimal 的使用、索引调整、事务边界、错误处理,以及使用 AS/400 数据样本进行的单元测试。
快速参考
关键迁移规则
- 始终对 RPG 打包(P)和分区(S)十进制数使用 BigDecimal,绝不使用 float/double
- 调整索引:RPG 数组/字符串使用从 1 开始的索引,Java 使用从 0 开始的索引
- 替换指示符:将 *IN01-*IN99 转换为描述性布尔变量
- 文件操作:CHAIN → findById(),READ → 使用 Optional 的查询方法
- 字符串函数:%SUBST(1:10) → substring(0, 10) — 调整位置
- 日期操作:将 RPG 日期函数转换为 LocalDate/LocalTime API
- 事务:识别 COMMIT 操作 → 使用 @Transactional 注解
- 错误处理:将 %ERROR/%STATUS 转换为带自定义异常的 try-catch
示例:将数据结构转换为 Java 类
RPG D-spec:
D Employee DS
D EmpId 6 0
D EmpName 30 A
D Salary 63 2P
Java POJO:
public class Employee {
private int empId;
private String empName;
private BigDecimal salary; // 6 digits, 2 decimals
// getters/setters
}
示例:文件操作转换
RPG CHAIN:
C custId CHAIN CUSTFILE
C IF %FOUND(CUSTFILE)
使用 JPA 的 Java:
customerRepository.findById(custId).ifPresent(customer -> {
// process customer
});
// Service usage
public class CustomerService {
@Autowired
private CustomerRepository customerRepository;
public Optional<Customer> findCustomer(Integer custId) {
return customerRepository.findById(custId);
}
}
边缘情况
情况 1:打包十进制数精度
问题:使用 double/float 会导致精度错误。解决方案:始终使用字符串字面量创建 BigDecimal:new BigDecimal("123.45")
情况 2:数组索引偏移
问题:RPG 从 1 开始,Java 从 0 开始。解决方案:调整所有数组/字符串索引引用。彻底测试。
情况 3:外部数据结构
问题:EXTNAME 没有 DDL 源。解决方案:使用 DSPFFD 命令、查询 DB2 SYSTABLES/SYSCOLUMNS,或根据运行时数据创建实体。
情况 4:旧式指示符
问题:使用 *IN01-*IN99 控制流程。解决方案:替换为描述性布尔变量:boolean invalidAmount = false;
情况 5:日期世纪处理
问题:两位数年份(Y2K)。解决方案:使用四位数年份的 LocalDate,应用世纪窗口逻辑,并记录假设。
指南
- 必须使用 BigDecimal:打包/分区十进制数绝不使用 float/double
- 使用有意义的布尔变量名:将 *IN01-99 替换为描述性名称
- 数据库访问:将文件 I/O 映射为 JPA/JDBC 操作
- JPA 实体:根据 EXTNAME 物理文件定义创建
- 异常处理:将 %ERROR/%FOUND 转换为异常/Optional
- 使用 AS/400 数据测试:通过实际旧系统数据进行验证
- 事务:识别 COMMIT 操作 → 使用 @Transactional
- 记录规则:提取并记录隐式业务逻辑
- 字符编码:验证 EBCDIC → Unicode 转换
- 批处理:将批处理作业转换为 Spring Batch 框架
错误处理
类型 1:文件 I/O 错误
检测:检查 %ERROR 或 %STATUS。处理:使用带自定义异常(CustomerNotFoundException、DataAccessException)的 try-catch
类型 2:算术溢出
检测:字段长度不足。处理:使用具有适当精度和小数位数的 BigDecimal,并捕获 ArithmeticException
类型 3:缺少依赖项
检测:缺少 /COPY 成员。处理:跟踪所有包含项,创建共享接口,并使用 Maven/Gradle 依赖项
其他资源
详细文档请参阅 references/ 目录:
RPG 翻译规则(按主题整理)
RPG 翻译规则按主题整理到不同文件中,便于查阅:
- pseudocode-rpg-rules.md - 主索引,包含快速入门指南和文件导航
- pseudocode-rpg-core-rules.md - 基础:规范、数据类型、基本操作、文件 I/O
- pseudocode-rpg-functions.md - 内置函数(BIF):字符串、日期/时间、数学、数组函数
- pseudocode-rpg-data-structures.md - 数据结构模式:QUALIFIED、LIKEDS、OVERLAY、I/O 规范
- pseudocode-rpg-patterns.md - 常见惯用写法、翻译模式、易错点、关键规则
- pseudocode-rpg-advanced.md - ILE RPG、嵌入式 SQL、Web 服务、IFS、XML/JSON、线程
- pseudocode-rpg-migration-guide.md - 迁移工作流、最佳实践、重构策略
其他参考文档
- pseudocode-common-rules.md - 通用伪代码语法和约定
- testing-strategy.md - RPG 到 Java 迁移验证的测试方法
- transaction-handling.md - AS/400 事务模式到 Java 事务管理
- performance-patterns.md - 迁移代码的性能优化模式
- messaging-integration.md - IBM i 系统的消息队列和集成模式
脚本
用于自动分析的 Python 和 shell 脚本,位于 scripts/:
analyze-dependencies.sh/ps1- 扫描 RPG 源代码中的 CALLB、CALLP、/COPY;生成依赖关系图extract-structure.py- 解析 RPG 规范(H、F、D、C、P);输出结构化 JSONgenerate-java-classes.py- 根据 RPG 数据结构创建类型适当的 Java POJOestimate-complexity.py- 计算迁移复杂度评分和工作量估算
模板
- migration-report-template.md - 迁移分析报告的标准格式
- java-class-template.java - 生成的 Java 类模板
analyze-dependencies.sh / .ps1
- 扫描 RPG 源文件中的 CALLB、CALLP、/COPY 引用
- 以 JSON 格式生成依赖关系图
- 识别循环依赖
用法:
./scripts/analyze-dependencies.sh /path/to/rpg/source
extract-structure.py
- 提取程序结构(H/F/D/C/P 规范)
- 列出所有变量、数据结构和文件
- 识别子例程和过程
- 输出 JSON 结构文件
用法:
python scripts/extract-structure.py PROGRAM.rpgle --output structure.json
generate-java-classes.py
- 根据 RPG 数据结构生成 Java POJO 类
- 创建合适的字段类型(打包十进制数使用 BigDecimal)
- 添加 getter、setter 和构造函数
- 生成 Bean Validation 注解
用法:
python scripts/generate-java-classes.py structure.json --output-dir ./src/main/java
estimate-complexity.py
- 计算迁移复杂度评分
- 分析 LOC、依赖关系和文件操作
- 提供工作量估算(小时/天)
- 生成优先级排名
用法:
python scripts/estimate-complexity.py structure.json --report complexity-report.md
模板
使用迁移报告模板,确保文档格式一致:
- migration-report-template.md - 迁移分析报告的标准格式
- java-class-template.java - 结构规范的生成 Java 类模板
与开发工具集成
此技能可与各种开发和分析工具集成:
IBM i / AS/400 工具
- Source Entry Utility (SEU):从 AS/400 提取源代码
- Programming Development Manager (PDM):访问成员列表和源文件
- WRKMBRPDM:处理源成员
- DSPFFD:显示文件字段描述,用于分析数据库结构
- DSPPGMREF:显示程序引用和依赖项
数据库工具
- DB2 for i:查询系统目录(SYSTABLES、SYSCOLUMNS)以获取元数据
- IBM Data Studio:可视化数据库设计和 SQL 开发
- DBeaver:支持 DB2 的通用数据库工具
现代开发环境
- IntelliJ IDEA:支持 Spring Boot 的 Java 开发
- Eclipse:配备 JPA 工具的 Java IDE
- VS Code:配备 Java 扩展的轻量级编辑器
- Git:用于管理旧版源代码和新的 Java 代码的版本控制工具
迁移支持工具
- Spring Initializr:快速创建 Spring Boot 项目
- JPA Buddy:用于生成 JPA 实体的 IntelliJ 插件
- Liquibase/Flyway:数据库迁移版本控制
- Maven/Gradle:构建自动化和依赖项管理
测试与验证
- JUnit 5:单元测试框架
- Spring Boot Test:集成测试支持
- Mockito:用于单元测试的模拟框架
- TestContainers:使用容器进行数据库集成测试