mcpField
R
rust-java-migration

rust-java-migration

github.com/full-stack-skills开发1287 次安装5 周前更新
代码仓库

关于 rust-java-migration

面向将 Java 项目迁移到 Rust 的团队,提供保留行为、映射源码结构和审计兼容性的指导。强调按批次推进、明确基线、建立清单及以证据验证。

主要功能

  1. 01Java 到 Rust 迁移流程
  2. 02包到模块的路径映射
  3. 03Crate 边界与工作区规划
  4. 04源码和测试清单
  5. 05布局审计与兼容性证据

适用场景

  1. 01规划完整项目或模块迁移
  2. 02继续现有 Rust 移植工作
  3. 03审计行为和 API 兼容性
  4. 04组织迁移测试与文档

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/full-stack-skills/rust-skills --skill rust-java-migration

安装后在 Claude Code 中输入/rust-java-migration确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

agents/
openai.yaml
assets/templates/
对象名称一致性检查.md
对象级对照表.md
语义迁移对照表.md
迁移路线图.md
examples/golden-migration/
Cargo.lock
Cargo.toml
examples/golden-migration/src/
agent_state_store.rs
agent_state.rs
in_memory_agent_state_store.rs
lib.rs
state_error.rs
examples/golden-migration/tests/
state_store.rs
references/
case-study-lessons.md
codegraph-parity-audit.md
comment-migration.md
compile-drift-and-cleanup.md
component-candidate-catalog.md
component-replacement-sop.md
crate-replacement-discovery.md
cross-language-migration-profile.md
directory-path-alignment.md
layout-and-governance.md
rust-api-adaptation.md
semantic-mappings.md
verification-and-acceptance.md
scripts/
audit_migration_layout.py
scaffold_migration_docs.py
scripts/tests/
test_audit_migration_layout.py
test_scaffold_migration_docs.py

详细介绍

Java 到 Rust 迁移

迁移契约和可观察行为,而不是 Java 语法。保留 Java 项目的公共概念和源代码可追溯性,同时选择 Rust 原生的所有权、错误处理、并发、异步、序列化和框架机制。

强制迁移布局

  • 根据声明的包根目录之后的 Java 包路径推导 Rust 目录;保留有意义的嵌套包,绝不扁平化、错置或重复嵌套。
  • 将 Java 对象名称转换为考虑首字母缩写的 snake_case.rs;Rust 类型保留 PascalCase,不要添加 _trait 等后缀。
  • 一个 Java 对象对应一个 Rust 对象边界。Rust 没有通用的文件长度限制:将最多 500 行物理行视为正常;对 501–800 行进行内聚性审查;禁止编写超过 800 行的 .rs 文件。
  • 仅当文件混合了不同职责时才拆分。保留一个主要对象文件,并使用从属文件承载内聚的实现系列,且不要引入第二个迁移对象;记录每次拆分或经审查的例外。
  • lib.rs 和 mod.rs 仅保留声明和重新导出。移动文件后更新父模块,并使用 :: 限定有歧义的外部重新导出。
  • 有用时,在 #[cfg(test)] 模块中保留针对私有行为的单元测试。将公共边界、跨模块、差异、宿主和整个项目的测试放在 tests/ 或非发布的 <project>-test 包中;将源代码夹具放在 <project>-test/tests/fixtures/。

阅读目录路径对齐和布局与治理,然后在移动文件后运行布局审计。

范围与路由

将此技能用于完整项目迁移、单个 Maven/Gradle 模块迁移、兼容性审计、迁移规划,或继续现有 Rust 移植。

这是跨语言迁移规范的 Rust 适配器。将 crate/布局/API、依赖项、宏和领域机制路由到对应的 Rust 技能。将验证路由到 rust-java-migration-testing 及相关测试技能。

如果用户只要求审计、计划或文档,则不要修改迁移代码。仅规划或只读请求不授权运行会生成文件的文档脚手架工具:在回复中提供拟议的四份文档内容、使用 --dry-run,或仅写入用户批准的目标位置。未经授权,不要将模块迁移扩大为整个仓库的重写。

必需输入

解决或明确标记未知项:

  • Java 仓库路径、基线提交或标签、构建工具、JDK 和模块范围。
  • 用于路径映射的确切 Java 模块包根目录;不要只传入仓库根目录或 src/main/java 根目录,然后猜测要去掉哪些路径段。
  • Rust 仓库路径、基线提交、工具链/MSRV、工作区和目标平台。
  • 目标产品拓扑输入:独立发布的 Rust 单元、依赖/功能/目标/过程宏/FFI 边界、预期 crate 数量、包系列、根目录噪声、其他语言和既定路径。
  • 兼容性目标:源代码形态一致、公共 API 一致、行为一致,还是生产环境替代。
  • 依赖策略:许可证、MSRV、支持的目标平台、不安全代码策略、公告策略、维护期限和可接受的传递依赖成本。
  • 组件候选来源及其观察日期;区分团队策略、调研候选项、已声明的依赖项和已验证的采用情况。
  • 明确的例外、受阻的外部项目、不支持的仅限 JVM 功能和完成期限。
  • 必需的宿主应用、真实脚本、测试数据、并发模型、负载配置和回滚机制。
  • 现有迁移文档及其权威性;在合并历史材料前,先确定唯一一套当前的四份文档。
  • 完整的源代码测试根目录/运行器配置,包括每个具体测试用例、已禁用的测试、测试夹具、脚本、语料库、黄金文件、资源和数据文件。源仓库定义分母;不要为了适配 Rust 而缩小范围。

绝不要在未说明的情况下推断,最新分支、生成的清单或 API 注册列表就是行为基线。

工作流

默认将一个已声明的 Java 源模块及其对应的 Rust 目标 crate/模块作为一个迁移批次。经用户授权的多模块范围可以作为一个批次,但必须在实施前冻结边界。按以下顺序执行:冻结范围/契约 → 实施该批次 → 冻结 → 审计 → 统一验证。

允许在实施批次中按依赖顺序编辑。不允许按对象逐个循环完成。

1. 冻结基线并检查仓库状态

记录两个仓库的 SHA、工作区是否有未提交更改、Java/Rust 工具链、模块清单、启用的功能和生成代码边界。保留现有 Rust 工作和无关更改。

验证 Rust 工具链满足工作区 MSRV:默认的旧版 rustc 会因 rustc X is not supported by the following packages 而失败——使用 rustup run <ver> cargo ... 运行检查门禁,绝不要暗中降低 rust-version。

如果仓库包含 .codegraph/,请在文本搜索或逐文件阅读前使用 CodeGraph:

  1. 调查模块/包/crate 架构。
  2. 查询具有代表性的公共类型和重载方法。
  3. 沿高价值调用链进行追踪,涵盖工厂、注册表、拦截器、序列化器、持久化、网络和并发。
  4. 查询对应的 Rust 代码及其调用方/测试。
  5. 如果索引报告已过时,则在实施前刷新模块清单或重新查询。

如果不存在索引,未经授权不得初始化。使用语言感知工具或有针对性的源码检查,并说明证据较弱。

阅读 CodeGraph 对等审计,了解查询模式和清单规则。 在设计大型工具库迁移或注解/宏拆分时,阅读 案例经验。

1.5. 推导 Rust crate 边界和工作区拓扑

不要将 Maven/Gradle 模块与 Cargo package 一一对应。应根据独立发布/复用、依赖/功能/目标隔离、proc-macro 或 FFI 约束以及不同的生命周期来划分 Rust package;源代码模块仍作为可追溯范围。

使用 rust-workspace 选择布局:规模较小且内聚的项目通常采用根目录扁平布局;存在实际的适配器/绑定/示例/测试系列时适合采用混合布局;大型、根目录内容繁杂或多语言仓库可能适合使用 crates/。数量仅用于触发审查,并非硬性规定。在路线图中记录源代码模块到 crate 的映射、所选拓扑、被否决的方案以及兼容性计划。参见布局与治理。

2. 在实施前建立清单

为以下内容分别创建机器可读或表格形式的清单:

  • Java Maven/Gradle 模块和 Rust crate。
  • 源代码模块到 crate 的映射,以及说明根目录扁平布局、混合布局或分组收纳路径为何适合本项目。
  • Java package 和 Rust 模块目录。
  • 类、接口、枚举、记录、注解、异常以及相关的内部类型。
  • 每个对象在移除组织/module package 根路径并保留剩余部分中最后两个片段后(不足两个时保留一个或零个)的确定性 Rust 路径。
  • 公有/受保护构造函数和方法,包括所有重载。
  • 参数名称、顺序、泛型约束、可空性、默认值、可变参数、受检异常和返回值约定。
  • 现有对象、构造函数、方法、泛型/值参数、返回值、异常、元数据标签和语义性内联注释,并注明源代码锚点。
  • 示例、测试、测试夹具、脚本、配置、资源、服务描述符和文档。
  • 源测试用例清单和资源清单;在将资源逐字节复制到 Rust 之前,记录每个具体用例和资源路径/哈希。
  • 一个不发布的 <project>-test package,负责项目级源代码重放、跨组件路径和差异验收。
  • 调用路径和可从外部观察到的副作用。

只有通过显式分类,才能排除 package-info、生成的源代码、BOM、聚合器、测试支持、门面和仅供 Rust 使用的基础设施。不要通过更改分母来隐去它们。

在修改生产代码前,将清单冻结为批次清单。覆盖完整分母、依赖顺序、共享机制、组件决策、测试处置和获批的例外;不要逐个对象发现工作范围。

从此 SKILL.md 确定 SKILL_DIR;绝不要假设固定的安装路径。从 Rust 迁移根目录运行命令,并优先使用相对于仓库的输入/产物路径。

尽早运行 Rust 静态布局审计,作为初步信号:

python3 "$SKILL_DIR/scripts/audit_migration_layout.py" \
  --java-package-root ../java-project/source-module/src/main/java/org/example/module \
  --rust-root . \
  --retain-segments 2 \
  --require-source-comments \
  --fail-on-warning

该脚本会计算预期路径,并区分缺失对象与位置错误的对象。它还会检测非 snake_case 路径、包含多个对象的文件、门面定义、通配符导入、存根宏/恐慌、空函数体以及缺少中文源代码注释的情况。对于获批的 501–800 行内聚性审查,使用重复的 --reviewed-large-file path/to/file.rs 记录;这不会豁免超过 800 行的文件。任何严格阻断项都会使迁移无法完成;即使扫描结果干净,也不能证明 Java/Rust 语义一致。

3. 为每个源模块创建四份文档

获得编写文档的授权后,在实现之前为每个 Java 模块生成一个文档目录:

python3 "$SKILL_DIR/scripts/scaffold_migration_docs.py" \
  --module source-module \
  --java-root ../java-project/source-module \
  --java-package-root ../java-project/source-module/src/main/java/org/example/module \
  --rust-root <selected-target-crate-or-workspace> \
  --output-dir docs/source-module \
  --java-baseline <sha-or-tag> \
  --rust-baseline <sha> \
  --retain-segments 2

该命令会创建:

  1. 迁移路线图.md — 范围、基线、阶段、依赖项、风险和证据关卡。
  2. 对象级对照表.md — 每个 Java 对象及其对应的 Rust 文件/类型/状态。
  3. 语义迁移对照表.md — 每类行为及其 Rust 原生实现。
  4. 对象名称一致性检查.md — 数量、缺失/额外/合并的对象、名称、方法、参数和逻辑缺口。

根据源代码证据填充所有占位内容。生成的模板属于 DRAFT,不构成证据,也绝不代表已完成。代码变更时同步更新文档。模板:

四份文档均须独立详尽,并包含模块当前的迁移约定:源代码/Rust SHA、精确对象分母、目标根目录、retain_segments = 2、状态快照、严格完成规则,以及该文档的职责。拒绝只有标题、只有数量或只有占位内容的文档。为防止内容流于摘要,至少要求三个有实质内容的二级章节,以及一个证据表或任务矩阵;使用仓库配置的篇幅下限(默认 45 个非空行),但对于确实很小的模块,生成的对象表可以按比例缩短。

每份文档都必须分别列出 Java 和 Rust 基线、最近审计日期及文档状态。每条已迁移/已验证的记录都需要证据锚点:源文件或符号、目标文件或符号、测试/判定基准、精确命令,以及适用时的产物。实现期间,不要逐条升级记录状态。批次冻结后,根据当前 Rust SHA 交叉核对全部四份文档,并在一次集中的更新中修改状态。后续的数量表不得与技术要求文档或更早记录的语义缺口悄然矛盾。

模块根目录只保留一套当前有效的四份文档。不要在其旁留下 *-历史详细版.md 或第二份 history/**/<current-name>.md。将有用的旧包分组、设计背景和决策历史合并到对应当前文档中,并明确标记为“历史设计附录”。生成的当前事实区域必须保持在文档最前面,重新生成时须保留附录。旧数量、路径、状态、测试和完成标记均不得覆盖当前事实。

将脚手架的 --force 视为破坏性操作,仅用于可丢弃且未经修改的 DRAFT;绝不可用它来合并或刷新已有内容的当前文档。应直接在当前文档中合并历史详情,同时保留其生成的事实区域和现有附录。

4. 如实分类每个对象

一致使用以下对象状态。将验证级别(V0–V7)分开处理;不要虚构一个更友好的状态,也不要将测试结果直接转换为对象状态。

StateMeaning
MISSING预期的 Rust 对象文件不存在
MISPLACED存在同名文件或类型,但不在确定性的预期路径下
STUB存在结构或占位内容,但缺少实际行为
PARTIAL存在实际行为,但方法、回调、错误、顺序、生命周期或集成语义不完整
UNVERIFIED文件或逻辑存在,但源代码注释、对象边界或语义测试证据不足
IMPLEMENTED预期路径、单对象边界、完整的实际逻辑、中文源代码语义和当前语义测试均已具备
DEPENDENCY_REUSED固定版本的依赖提供了完全相同的能力;已记录 crate/版本或提交、上游符号、适配器和本地集成测试
PLATFORM_NA该能力确实仅适用于 JVM/字节码/类加载器/平台,并且有明确证据说明为何不适用 Rust 对象
RUST_EXTENSION有意提供的 Rust 专属能力,不计入 Java 同等实现的分母

只有 IMPLEMENTED、DEPENDENCY_REUSED 和 PLATFORM_NA 才算处理了源对象。MISSING、MISPLACED、STUB、PARTIAL 和 UNVERIFIED 均为未完成状态。RUST_EXTENSION 永不计入 Java 分母。

只有在用户明确批准时,才允许使用计划中的占位内容。在路线图中记录阻塞因素,但让每个受影响对象保持其实际的 MISSING 或 STUB 状态。阻塞因素是元数据,不是类似完成状态的对象状态。

绝不能仅因为对象名称出现在清单、门面、lib.rs、mod.rs、重新导出、生成的注册表或兼容性模块中,就将状态从 MISSING 提升。绝不能仅因为 cargo test 全部通过,就将状态从 UNVERIFIED 提升。

5. 根据契约决定组件替换方案

不要直接映射框架名称。对于每个外部 Java 组件或框架子系统:

Java 源模块仍是对象名称、包结构和公共契约的权威依据。Rust 依赖项只是复用实现的边界。不要围绕依赖项的文件树重新组织迁移,也不要仅为提高对等性计数而将依赖项自有实现复制到本地文件中。例如,对于类似 AOP 的工作,Spring 定义 Advice/Interceptor/Advisor 对象清单,而 aspect crate 可以通过 DEPENDENCY_REUSED 满足特定运行时符号。

  1. 提取行为契约:API 形态、网络传输/存储格式、顺序、故障分类、生命周期、事务、并发、取消、背压、安全性、可观测性和部署假设。
  2. 选择替换形态:标准库、直接使用 crate、封装 crate、trait 加适配器、显式注册表/SPI、编译时宏/代码生成、由应用宿主负责,或已证实的 PLATFORM_NA。
  3. 将常见映射表和候选目录作为发现的起点,而不是自动批准依据。
  4. 如果没有经过验证的映射符合要求,则生成多个英文能力/协议/约束查询,在 crates.io 和配套的权威来源中搜索,并从 std、直接使用 crate、封装、trait/适配器、代码生成、宿主负责和排除等形态中筛选出 5 到 10 个候选项。
  5. 如有可用的 rust-crate-discovery,将 crates.io 元数据收集和生态健康度比较交由它处理。在此处应用迁移专用的契约和兼容性门槛;其数值健康评分不能决定替换方案。
  6. 在评分前,淘汰不满足所需契约、许可证、MSRV/目标平台、运行时/阻塞行为、协议、安全性、维护/所有权或依赖图约束的候选项。
  7. 根据语义契合度、维护情况、采用情况、文档/测试、项目兼容性、安全性/供应链、成熟度、成本和退出策略,对可行候选项进行比较。将下载量、反向依赖数、星标数、最近发布时间和提交记录视为背景信号,而非证明。
  8. 在确定架构前,先针对排名靠前的候选项,对风险最高的语义路径进行原型验证。
  9. 记录搜索查询和日期、所有权、版本/功能、各维度的证据/置信度、被拒绝的替代方案、退出方案和回滚计划。
  10. 只有在记录了确切的上游符号、固定版本的依赖证据、适配器边界和本地集成测试后,才将对象标记为 DEPENDENCY_REUSED。“生态中有这个”或“语义相似”仍属于 UNVERIFIED。

对于多个目标框架,应定义框架无关的契约和轻量适配器,然后针对每个适配器运行同一套一致性测试。运行时 traits/类型应与轻量过程宏和生成的代码分开。

在选择或批准第三方替换方案前,请阅读 组件替换决策 SOP、crate 替换方案的发现与评估 和 组件候选目录。目录仅用于发现候选项,不代表批准清单;在决策时,应重新核实发布情况、维护情况、许可证、MSRV、目标平台、安全公告、unsafe/构建脚本影响范围以及所需契约。

6. 在一次语义实现过程中完成已声明的批次

修改代码前,先阅读 目录结构与迁移规则、 目录路径对齐模式与错误目录 和 语义映射。然后执行整个已冻结批次,不要在对象级验收时暂停:

  1. 一次性建立目标模块树、共享错误、trait、注册表、适配器、序列化规则、并发模型和依赖边界。
  2. 按依赖顺序实现每个映射的 Java 对象和操作。每个 Java 对象恰好保留一个主 .rs 文件,并在对应对象文件或显式协作者文件中实现实际逻辑。
  3. 在整个批次中,将 JavaDoc 语义复制并翻译为中文 Rust 文档注释。逐一迁移每个现有的对象注释、构造函数/方法注释、泛型和取值 @param、@return、@throws、@since、@deprecated、相关的 @see 以及语义性行内注释,不得遗漏。保留针对具体参数的约定。将 Java 到 Rust 的名称、签名和异常映射保留在四份迁移文档中;生成的 Rust 文档应采用 Rust 原生形式。
  4. 将所有映射的重载变体、示例、fixture、源测试对应项、Rust 特定义务和基于风险的测试作为批次产物实现,但暂不执行验证。完整保留 100% 的源测试输入、断言、错误预期、状态、副作用和清理操作。复制源测试文件/数据/资源,不得编辑;任何 Rust 特定派生内容都应放入单独文件。
  5. 维护一份待处理问题清单。继续处理本地不确定事项;仅当阻碍会改变已冻结的公共约定、架构、依赖策略或授权范围时才暂停。
  6. 所有非豁免清单行均已完成实际实现后,冻结 Rust 批次。此后才可批量更新四份文档并进入审计阶段。

在此过程中,不要运行 cargo check、测试、Clippy、覆盖率检查、差异比较、逐对象 CodeGraph 重新查询或逐对象完成情况审查。不得仅因某个对象的文件已编辑就报告该对象已验收。允许提交恢复性代码,但这些提交不属于验证关卡。

迁移文档前,请先阅读 注释迁移约定与示例。将缺失的源注释视为迁移缺漏,而非可选的清理工作。

7. 保留命名和重载意图
  • Rust 目录、文件、方法和参数使用 snake_case。
  • Rust 类型使用 PascalCase。
  • 将 loadOrCreateAgentState(slotKey) 映射为 load_or_create_agent_state(slot_key)。
  • 移除组织名和声明的源模块包根目录,然后保留最终剩下的两个包段。若只剩一个,则保留该段;根包对象放在 crate 根目录。例如: factory/xml/support/Foo.java → xml/support/foo.rs; propertyeditors/PatternEditor.java → propertyeditors/pattern_editor.rs。
  • lib.rs 和 mod.rs 仅用于声明和重新导出。
  • 每个 Rust 文件保留一个 Java 类/接口/枚举/记录;与主类型紧密关联的内部构建器可以与其放在一起。
  • 将 500 行物理代码视为内聚性审查阈值,将 800 行视为自编写文件的阻止阈值。按职责拆分,而非按行数范围拆分;子文件不得引入其他已迁移对象。
  • 启用 clippy::too_many_lines,将其默认的 100 行阈值作为函数/方法审查信号;当长例程组合了不同职责时,应进行重构。
  • 遵循 Rust 惯用的测试组织方式:将针对性单元测试放在 #[cfg(test)] 模块中;将公共边界、跨模块、差分、宿主和整个项目的测试放在 tests/ 或测试/testkit 包中。
  • 在对象文档和命名一致性文档中记录每项有意的重命名。

Rust 不支持方法重载。只有当签名代表同一种语义操作时,才保留一个规范的 snake_case 名称。为其他变体添加稳定的语义后缀,例如 _with_charset、_into 或 _from_reader;记录每个 Rust 函数对应的确切 Java 签名。绝不能合并默认值、验证、副作用或错误行为不同的重载。

对每个已迁移的公共 Rust 接口,都应用本地的 rust-api-design 约定。不要机械地翻译 JavaBean 访问器:优先使用 name() 而非 get_name()(真正的查找操作除外);使用 set_name(value) 进行受控变更;仅在不会绕过不变量时使用 name_mut();使用 into_name()/into_inner() 转移所有权;使用语义明确的布尔谓词和可链式调用的构建器。按照 Rust 的语义使用 as_/to_/into_、From/TryFrom/AsRef 和 IntoIterator;不要使用 Deref 模拟 Java 继承。只有在不变量和 API 演进允许时,才直接公开字段。保留验证、可见性、副作用、异常、同步和惰性计算行为。

当脚本、表达式引擎、序列化器、反射门面或其他兼容性接口公开 Java 属性语义时,应保持 Rust API 惯用,并在显式注册表或成员解析器中实现旧有的字段/getter/setter 行为。将此关系记录为映射形式 ADAPTED;它与完成状态正交,仍需记录 IMPLEMENTED、UNVERIFIED 或其他符合事实的状态。

迁移 getter、setter、构建器或脚本可见属性之前,请阅读 Rust API and JavaBean property adaptation。

8. 翻译机制,而非照搬框架

将此表作为通用起点,然后核实确切契约和当前 crate 证据:

Java 职责Rust 起点
Jackson JSON 注解/模块serde、serde_json、项目自有的自定义序列化器
Jackson XML / JAXB 风格的 XMLquick-xml,以及显式的命名空间、属性、混合内容和顺序逻辑
null、受检异常Option<T>;类型化的 thiserror 枚举和 Result
SLF4J/Logback/MDCtracing、tracing-subscriber、显式的字段/上下文传递和脱敏
synchronized / ConcurrentHashMap优先考虑所有权;然后根据访问模式,使用标准库的 Mutex/RwLock 或 DashMap
CompletableFuture、定时执行器异步 Future、受监督的 Tokio 任务、取消令牌、定时器/间隔器;只有在需要更丰富的契约时才选择调度器 crate
Reactor Mono<T> / Flux<T>async fn -> Result<T, E>;有界的 Stream<Item = Result<T, E>>
OkHttp / Apache HttpClient用于高级客户端的 reqwest;用于协议级控制的 Hyper;验证 TLS、代理、连接池、重定向、重试和流式处理语义
Spring MVC/WebFlux / JAX-RS与框架无关的核心,加上经批准的 Axum、Actix Web、Poem 或其他轻量宿主适配器
JDBC/JPA/MyBatis根据查询、映射、事务、迁移和运行时契约,选择 SQLx、Diesel、SeaORM、RBatis 或其他经过验证的数据层
Caffeine/Guava 缓存Moka 或项目自有缓存;验证逐出、TTL/TTI、加载、失效和并发行为
Jedis/Lettuceredis;验证集群/sentinel、重连、管道/事务、TLS 和异步行为
Kafka/RabbitMQ/Pulsar/NATS/MQTT特定协议的客户端,例如 rdkafka、Lapin、pulsar、async-nats 或 rumqttc;要求具备真实 broker 语义和恢复测试
Protobuf / gRPCProtobuf;用于 gRPC 的 Tonic 和 Protobuf
Bean Validationvalidator 或项目自有验证,并与框架提取器分开
java.time、UUID/ULID、BigDecimal、正则表达式time/chrono、uuid/ulid、rust_decimal/bigdecimal、regex;在优先选择 crate 之前,先确定表示形式和兼容性
.properties、YAML、TOML、配置绑定java-properties、serde_yaml_ng、toml 或经过验证的配置 crate,加上项目自有的优先级/配置档规则
Apache Commons/Hutool 通用工具优先使用标准库,然后使用 url、bytes、regex、base64 或 hex 等专用 crate;不要按名称寻找一个包罗万象的 crate
Micrometer/OpenTelemetry/Prometheusmetrics、OpenTelemetry 生态、Prometheus 导出器和 tracing 集成;保留名称、标签、基数、上下文和关闭行为
JavaMaillettre;验证 MIME、附件、TLS/身份验证、重试和投递报告
JWT/密码/通用加密jsonwebtoken、argon2 和专用 RustCrypto crate;根据安全契约选择算法/格式,绝不能只考虑便利性
Groovy/Nashorn/嵌入式脚本根据语言、沙箱、资源限制、线程和打包要求,选择 rhai、boa_engine、mlua、PyO3 或 Wasmtime
Apache POI/文档格式特定格式的 crate,例如 rust_xlsxwriter、calamine、docx-rs、printpdf 或 lopdf;使用实际的 Office/PDF 样例验证不支持的功能
ServiceLoader/SPI优先使用显式注册表;仅在需要链接时注册时使用 inventory
Spring IoC/AOP/运行时注解构造函数/构建器、trait、中间件、注册表、包装器;仅在需要编译时行为时使用宏
FreeMarker / Velocity / 编译时视图Tera / Handlebars;编译时模板使用 Askama;Rust 原生标记使用 maud
Lombok 数据样板代码使用标准派生宏,以及保留不变量的 API/构建器;仅根据生成的 API 契约评估 lombok-macros
JUnit/TestcontainersRust 单元/集成测试;使用 testcontainers 管理可丢弃的真实依赖
JNI/手动 Swift/Kotlin/Python 绑定当 UniFFI 支持的类型/错误/异步模型满足需求时使用;交付和打包仍需单独处理
优先组合成熟的 Rust crate,而不是重新实现 Java 全家桶,但在兼容性有要求时,保留源项目可观察到的外观。
9. 在稳定的宏边界后提取注解行为

不要将过程宏入口放在普通运行时 crate 中。请使用:

project-core      # runtime traits, types, errors, and generated-code contract
project-macros    # thin proc-macro entry points and syntax parsing
project-web-*     # framework adapters that may re-export approved macros

仅当公共接口只有派生宏时,才使用 -derive;对于属性宏、类函数宏或混合宏,使用 -macros,除非现有 crate 系列已约定使用其他命名。生成的代码应依赖公共运行时 API,而不是过程宏内部实现。测试展开成功、编译失败、泛型、可见性、依赖重命名,以及每个框架的重新导出。

Java 运行时注解不会自动变成 Rust 宏。如果行为由运行时状态和动态分发决定,请使用中间件、trait、注册表或显式构建器。

10. 一次性审计,然后验证完整批次

实现冻结后,对整个已声明批次执行适用的验证流程:

  1. 对所有对象、文件、精确签名、参数、重载、调用路径、动态边界、示例、测试、文档和占位符,执行一次整合式 CodeGraph/静态对等性审计。将完整的 Java 注释清单与 Rust 对象、方法、参数、返回值、错误、元数据和行内注释进行比较。一次性协调全部四份文档。
  2. 将 Rust 格式检查、检查、单元测试、文档测试、集成测试、Clippy、特性、目标平台和平台门禁作为一套统一的工程验证套件运行。
  3. 运行所有已移植/镜像的 Java 契约测试,并明确标注为非差分证据。
  4. 运行完整的固定版本 Java 测试套件和完整的 Rust 无损移植测试套件,然后对每个具体源用例运行完整的 Java 黄金测试导出器或实时 Java/Rust 差分测试套件。要求两个测试套件都通过,且每个用例均报告 MATCH;不允许有不匹配、测试框架故障或未运行用例。请从专用的 <project>-test 包中执行;本地生产 crate 测试仅作为子系统证据。
  5. 针对两种实现,重放全部真实用户脚本和示例。
  6. 在适用时,运行并发验收,检查顺序、取消、背压、竞态、关闭以及 Loom/模型属性。
  7. 运行负载/稳定性测试,检查吞吐量、延迟百分位数、内存、句柄/任务、重连和长时间运行情况。
  8. 运行安全属性测试、畸形输入测试套件、cargo-fuzz、不安全代码审查、依赖项安全公告检查和机密信息脱敏检查。
  9. 使用数据库、网络、文件、框架和部署拓扑,进行真实业务宿主集成。
  10. 执行灰度发布和回滚演练,并记录恢复时间和状态兼容性。

如果某个门禁失败,请按共用子系统或根因归类问题,修复整个批次,然后重新运行受影响的整合式门禁及其后续失效门禁。切勿退回到逐个对象迁移、比较和测试。

请阅读验证与验收,了解如何设计证据;并使用 rust-java-migration-testing 了解三账本测试 SOP。在修复无法编译或警告过多的工作区之前,请阅读编译偏移与迁移清理:依赖项/版本偏移、MSRV、crate 根重新导出链中断、跨 crate 类型重复、Java 镜像命名/脚手架规范,以及零警告检查工作流(默认配置 + --all-features、分层报告错误的 --keep-going、按 crate 归因、清理后运行测试)。

11. 在不夸大覆盖范围的情况下报告完成情况

分别报告结构、实现、行为、测试、集成和生产就绪情况。对于行为,区分镜像契约、黄金差分、实时差分和获批的等效判定依据;对于测试,区分无损迁移的源测试和 Rust 原生新增测试。

列出确切的命令、SHA、测试数量、失败情况、例外情况和未经验证的边界。绝不能仅仅因为代码可以编译或一致性清单达到 100%,就称迁移已完成。

红线

  • 不要在 lib.rs、mod.rs 或 compat.rs 中定义许多迁移对象。
  • 不要将每个对象都委托给同一个 compat.rs 实现。
  • 不要用空函数体、todo!() 或 unimplemented!() 冒充已完成迁移。
  • 不要为了让数量对得上而删除或简化已迁移的可用行为。
  • 不要在生产迁移代码中使用通配符导入。
  • 不要悄悄将多个 Java 对象合并到一个 Rust 文件中。
  • 不要让手写的 .rs 文件超过 800 个物理行;检查每个超过 500 行的文件,若内聚性较差,就将其拆分。
  • 不要为了满足大小门槛而机械压缩代码、删除有用的注释,或随意按行数范围拆分文件。
  • 不要将集成、差分、宿主、负载或全项目验收测试套件嵌入生产模块;内联的 #[cfg(test)] 单元测试仍可用于测试聚焦于模块私有行为的场景。
  • 不要用一个有损的便捷函数取代重载行为。
  • 如果符合 Rust 惯用写法的方法加上显式兼容适配器即可保留约定,就不要仅仅为了模仿 JavaBean 的命名而创建 get_* 方法。
  • 如果脚本或动态成员访问仍需要 Java 字段、getter、setter 解析,就不要认为惯用的 Rust getter/setter 已经足够。
  • 不要把声明依赖、成功编译或独立 POC 称作经过验证的组件替换。
  • 不要以替换依赖项的包或文件布局作为目标对象清单;源 Java 对象和确定性路径规则仍是权威依据。
  • 如果没有固定的 crate/commit、准确的源符号、适配器证据和本地集成测试,就不要将语义相似的依赖项标记为 DEPENDENCY_REUSED。
  • 不要将仅仅难以处理或缺失的工作标记为 PLATFORM_NA;必须提供 JVM/字节码/类加载器/平台特定的证据。
  • 没有当前的硬性筛选和契约证据时,不要仅凭研究清单或本地约定文档中的内容,就将组件提升为“已选定”。
  • 除非 Java 和 Rust 两种实现都参与测试,或有 Java 生成的黄金产物参与测试,否则不要将从 Java 测试复制来的 Rust 测试称为差分测试。
  • 不要仅凭处置结果声明源测试已达到对等。每个源用例都需要无损的目标,并且黄金结果/实时结果为 MATCH;MISSING、BLOCKED 和 NOT_APPLICABLE 都会阻止完成。
  • 不要就地修改复制的源夹具、脚本、语料库、黄金文件或测试数据。验证源和目标的 SHA-256,并将生成的派生文件分开保存。
  • 不要把各套件分别通过或测试总数相同视为对等;应逐个比较输出、错误、状态、副作用和清理情况。
  • 不要用生产代码/绑定 crate 的本地测试替代未发布的 <project>-test 全项目验收包。
  • 除非有 Rust 发布、依赖、目标平台、宏/FFI 或生命周期方面的理由,否则不要将 Maven/Gradle 模块一对一复制成 Cargo 包。
  • 不要强制所有工作区都采用 crates/ 布局或根目录扁平布局;应根据产品规模、模块族、仓库噪声和兼容性记录拓扑结构。
  • 不要仅凭文件数量、解析器接受、通用的 is_ok()/is_err(),或“每个对象至少一个测试”就将某一行标记为已通过行为验证。
  • 不要让四份迁移文档采用不同的基准或互相矛盾的完成状态。
  • 不要同时保留当前文档和 -历史详细版/嵌套副本;应将有用的历史内容合并到生成事实区域之后。
  • 不要替换生成的当前事实区域,也不要让重新生成操作丢弃已合并的附录。
  • 如果只运行了 mock、编译或静态检查,就不要声称进行了实际测试。
  • 提取模式时不要编辑参考源仓库。
  • 不要针对每个对象、文件或方法交替进行迁移、比较和测试。
  • 实施期间不要运行对象范围的验收测试;应先完成冻结批次,再进行集中审计和统一验证。
  • 不要将恢复提交或本地编辑里程碑转化为完成检查点。
  • 不要遗漏现有 Java 对象、构造函数、方法、参数、返回值、异常、生命周期、线程安全性、弃用信息或语义性内联注释。
  • 不要用通用文字替换源文档,也不要仅凭 cargo doc 就声称注释已对等。
  • 不要在参数、返回值、错误变体、字段或内联注释中写 对应 Java。可选的对应关系提示仅限于 Rust 类型和构造函数/方法文档;详细对应关系应保留在四份文档中。
  • 不要为了消除 non_camel_case_types/dead_code 警告而重命名 Java 镜像 SCREAMING_SNAKE 枚举变体,或删除 Java 镜像脚手架类型;应使用 #[allow(...)] 并添加注释,保留完整的 Java 清单。
  • 不要仅凭默认 features 门槛就宣称工作区干净;--all-features 也必须达到零警告。不要为了匹配较旧的本地 rustc 而悄悄降低 rust-version,应通过 rustup run <ver> cargo ... 运行固定工具链。
  • 清理依赖 crate 时不要编辑路径依赖项;应先根据 --> 路径将每条警告归属到对应的 crate。
  • 不要试图修复一次 --keep-going 输出中的“所有错误”;错误会分层出现——先修复第一层,再重新运行并迭代。

完成标准

  • 每个源模块的四份现行文档共享基线、契约和 Rust SHA;不存在重复项。
  • 路线图记录了有依据的源模块到 crate 的边界及由项目驱动的拓扑;实际清单和成员路径与之相符。
  • 每个对象都有确定性的末尾两段路径;在物理位置对齐之前,MISPLACED 始终视为未完成。
  • 每个 Java 对象、方法、重载和参数都有处置结果。
  • 每个源测试/用例都有无损的 Rust 实现,每项源资源都有逐字节一致的校验副本。
  • <project>-test 是位于选定路径的工作区成员,设置了 publish = false,并负责完整的源测试套件/差异测试命令及产物。
  • 完整的 Java/Rust 测试套件均通过,逐用例差异测试结果 100% 为 MATCH,且不存在测试框架失败或未运行的用例。
  • 每项依赖复用、平台排除、阻塞项、例外和 Rust 扩展都有精确证据,并如实处理分母。
  • 每个编写的 .rs 文件最多 800 个物理行;超过 500 行的文件和超过 Clippy 100 行提示阈值的函数均已记录内聚性审查,且任何拆分都保留 Java 对象边界。
  • 仅当单元测试用于测试聚焦的模块行为时才与代码放在一起;集成、差异、宿主、负载和整个项目的测试套件均放在 tests/ 或不发布的测试包中。
  • 生产用 Rust 文件符合布局、文档、导入和无存根规则。
  • 每个源文档记录的对象、成员、参数、返回值、异常、元数据标签和语义内联注释,都有可追溯的 Rust 对应项。
  • 在运行任何验收门禁之前,已实现完整的既定批次。
  • 一次整合的实现后奇偶一致性审计覆盖完整的冻结分母;未使用逐对象验证循环。
  • 高价值调用链都有源代码链接的语义映射。
  • 适用的差异测试、回放、并发、负载、模糊测试、宿主和回滚门禁均有证据或明确列出的未解决问题。
  • 最终报告分别说明结构、实现、行为、集成和生产就绪情况。

评论

支持 Markdown