Java 现代化:让企业级升级切实可行
走进任何一家大型企业——银行、航空公司、电信运营商——Java 通常都在承担最繁重的工作。核心银行系统、欺诈检测管道、订单管理、在日出前完成数百万笔交易对账的夜间批处理作业。它能运行,能扩展——而正是因此,大量系统至今仍在 Java 8 甚至更早的版本上运行。
能运行和健康运行是两回事。各框架停留在不再接收安全补丁的版本上。最初的开发者早已离开。"别动它,能用就行"已经演变成一种架构原则。差距还在不断扩大:records、sealed classes、pattern matching、virtual threads、G1/ZGC 收集器、更好的容器感知能力以及更快的启动速度——这一切都在一次没有人愿意安排的升级的彼岸等待。
这篇文章讲的就是如何缩小这一差距。它解释了这些应用程序为何被困住,然后逐一介绍 Premium Package for Java 的五项能力——JDK 版本升级、Liberty 迁移平台、UI 现代化、单元测试生成和安全修复——以及每项能力如何在确定性自动化与 AI 之间分配工作。最后会说明仓库需要做好哪些准备、如何获取访问权限,以及如何开始。
为什么这么多 Java 应用落后了整整十年
如果现代化如此明显地值得,为什么那么多企业 Java 应用看起来还冻结在 2014 年前后?原因是结构性的:组织惯性与真实的工程风险。
- 有机增长,而非规划增长。 这些系统一个功能一个功能、一次收购一次收购地成长起来。代码层叠加在更早的代码层之上,每一层都是在不同的截止日期和规范下写就的。你今天继承的代码,像极了地质沉积物——十年间数十个团队的决策积累。
- 编写核心模块的工程师早已离去,隐性知识也随之消失。留下的是稀薄的文档,以及几位"大概记得那个模块怎么运作"的资深工程师。
- 升级 Java 意味着依赖审查、框架升级(Spring、Hibernate、Jakarta EE 命名空间迁移)、废弃 API 的移除,以及在每个环境中的重新验证——数月的工作量、真实的预算和真实的机会成本,在系统本已运行良好的情况下很难说服人。
- 即使只是从 Java 8 跳到 17 或 21,也可能暴露出模块系统冲突、已移除的内部 API(
sun.misc.Unsafe)、变成硬错误的 reflection 警告,以及垃圾回收器行为的细微变化。纸面上的版本升级在实践中会变成数周的调查。 - 回归周期很长。 庞大的测试套件——单元、集成、性能、UAT,有时还有手动审批——意味着一次升级可能在发布前触发数周的测试。
- 一切之下是:害怕弄坏正在运行的东西。当一个应用每天处理数百万元的业务时,一次糟糕部署的代价远超不升级的代价——于是升级的讨论被推到下个季度。再下下个季度。
出路是增量式的,而不是重写。有了合适的工具,你可以用足够小的步骤偿还技术债,每一步都可以安全地发布。
Premium Package for Java
Premium Package for Java 是面向企业 Java 现代化的五个工作流套件。每个工作流都建立在同样的分工原则上:让确定性自动化做可预测的机械性工作,让 AI 处理那些靠规则无法编码的上下文决策。
基于规则的引擎(如 OpenRewrite)在数千个文件上进行机械性重构时表现可靠。AI 则更擅长处理混乱的部分——解读构建错误、推理业务逻辑、在权衡之间做选择。Bob 在一个逐步执行的工作流中编排两者,由人来审批重要的步骤。
背后的专业知识在这里很重要。这些工作流由曾构建 JIT 编译器、发布 WebSphere 和 Open Liberty、参与 Quarkus 先驱工作,并为 OpenJDK、Jakarta EE 和 MicroProfile 做出贡献的 IBM 和 Red Hat 工程师共同打磨。工具将这些团队的迁移方法论编码其中——这是模型仅凭眼前的代码无法重建的知识。
以下是五项能力上的分工情况。
能力 1:JDK 版本升级——从 Java 8 到 11、17、21 或 25
JDK 升级是最常见的现代化任务,也是最容易被低估的。Bob 将它视为一段多阶段的、以证据为驱动的旅程,而非单一命令。
- 先做项目分析。 Bob 分析构建工具(Maven 或 Gradle)、模块拓扑、当前 Java 版本和框架使用情况,然后提出可行的升级路径(8→17、8→21,是否含 Jakarta EE),每条路径都标注了难度评级和预期的技术挑战。
- 对于选定的目标版本,精选的 OpenRewrite 规则以安全、大规模的方式处理机械性转换。
- 规则能覆盖其中一部分——实践中大约 40–50%。剩余部分——特殊的依赖冲突、已删除的内部 API、特定库的兼容性问题——正是智能体循环介入的地方。Bob 编译项目,解析 Maven/Gradle 构建日志,按根因对异常分组,然后逐模块向 AI 请求针对性的修复。
- 尊重意图的护栏。 AI 被明确指示不得悄悄地在
javax和jakarta命名空间之间切换,不得为了"让代码能编译"而注释掉代码或移动文件,并在任何包或依赖变更前请求明确审批。
最终你得到的升级,在可以自动化的地方很快,在不能自动化的地方很谨慎——并在最后留下完整的审计跟踪。
能力 2:Liberty 迁移平台——从传统 WebSphere 到 Liberty
从传统 WebSphere Application Server 迁移到 WebSphere Liberty 或 Open Liberty,可以获得更低的内存占用、对容器友好的打包方式、更快的启动速度和现代 Jakarta EE 支持。这也是手动操作时最为复杂的迁移之一。
- AMA 驱动的评估。 Bob 读取 IBM Application Modernization Accelerator 的输出,将其报告解析为具体的、文件级别的迁移问题,并附带基于规则的修复建议。
- 每条 AMA 规则都携带规范性指导——"将
com.ibm.websphere.*替换为 Jakarta EE 标准等效项","将ibm-web-ext.xml配置迁移到server.xml"。Bob 将这些问题按根因分组后连同规则帮助文本一起传给 AI,让模型直接应用已知的修复方案而非猜测。 - 当迁移涉及 Jakarta 命名空间跳跃时,同一个 OpenRewrite 规则库以确定性方式处理命名空间的转换工作。
- 构建、部署、验证。 Bob 构建 WAR/EAR,通过
liberty-maven-plugin或liberty-gradle-plugin部署,追踪服务器日志中的启动和类加载失败,并以迭代方式解决它们。用curl对 REST 端点进行功能验证是标准流程的一部分。
该工作流将 Liberty 工程师的迁移方法论编码进来,而非将它交给一个通用的提示。
能力 3:UI 现代化——从 JSP/Struts 到现代 SPA
大多数遗留 Java 应用仍通过 JSP、Struts 或 Servlet 驱动 UI。Bob 将其拆分为五阶段的管道。
- 架构提取。 在任何代码重写之前,Bob 先分析应用,生成一份
architecture.md,将每个控制器、action、Servlet、页面、表单、验证规则和数据流路径都编录进去。该文档是后续迁移工作的唯一真实来源。 - 遗留表现层(Struts actions、Servlet、JSP 控制器)被转换为现代后端(Spring Boot、Quarkus 或 Liberty)上的 REST 端点,同时保留原有的 DAO 和模型类不动,以保护数据库完整性。
- 前端脚手架。 一个新的 TypeScript 项目(Angular、React 或其他框架)与所选的设计系统(Carbon、Material UI 或 shadcn/ui)连接,在任何功能开发开始前,HTTP 客户端、主题、路由、状态管理、错误边界和 CORS 均已配置完毕。
- JSP 表单和表格随后被映射到设计系统的等效组件——DataTable、Card、DatePicker、验证过的表单——并保留原有的业务规则。
- 每个步骤的验证门控。 Bob 从不自行启动应用。每个阶段结束后,它会请开发者运行构建/启动命令并确认,将验证权留在人类手中。
AI 处理从 JSP 标签汤到现代组件的上下文翻译;自动化处理脚手架、依赖和构建验证。
能力 4:单元测试——先制定策略,再生成测试
测试覆盖率通常是现代化最大的单一障碍:无法安全验证的东西,也无法安全升级。Bob 在生成测试之前先生成测试策略。
- 策略生成。 Bob 分析项目,生成一份
UNITTEST.md,涵盖架构、需要覆盖的模块、推荐的框架(JUnit 5、Mockito、AssertJ)、命名规范、覆盖率阈值,以及带和不带覆盖率报告运行测试的精确命令。 - 候选项选择支持多个粒度——整个包、特定类、单个方法——也可以基于 git diff 运行,将精力集中在最近改动的代码上。
- 生成、运行、修复。 每个测试提示都以同一条指令结束:运行测试,修复失败。AI 执行、观察失败,并迭代直到测试套件变绿,而不是停留在代码生成阶段。
- Bob 与 JaCoCo 集成,让循环以测量到的覆盖率为目标,而不仅仅是一次绿色的测试运行。
自动化运行测试;AI 编写测试并对失败进行推理。由此产生的覆盖率正是解锁另外四个工作流的关键。
能力 5:安全修复——作为同一循环的一部分的 CVE
一个完成了现代化却仍然携带充满 CVE 的依赖的应用,只做了一半。安全修复复用与 JDK 升级相同的架构,指向安全漏洞。
- 构建驱动的检测。 Bob 复用升级工作流中的 Maven 和 Gradle 日志分析器,专门调优以从构建输出、dependency-check 插件和 SBOM 工具中检测依赖建议、弃用警告和已知有漏洞的传递性依赖。
- 当一个修复不是简单的版本升级时——比如打了补丁的库更改了签名,而调用点需要迁移——智能体循环按根因将问题分组,跨模块应用修复,然后重新构建以验证。
- 同样的护栏同样适用。 没有明确审批不更改依赖,不注释代码,不搞命名空间意外。修复在落地前会被呈现、解释并确认。
安全加固与其他现代化工作在同一条轨道上运行,而不是作为单独的路线图。
共同主线
在五项能力中,同样的分工始终成立:
| 阶段 | 负责方 |
|---|---|
| 项目分析和元数据提取 | 自动化 |
| 机械性的、已知的转换 | OpenRewrite 规则 |
| 构建、日志解析、错误分组 | 自动化 |
| 上下文决策、错误修复、代码翻译 | AI |
| 审批门控、验证、部署 | Human-in-the-loop |
| 审计跟踪(Mermaid 图表、任务摘要、成本追踪) | 自动化 |
自动化处理确定性的事,AI 处理上下文性的事,人类审批重要的事——背后有构建了底层平台的 IBM 和 Red Hat 工程师的支撑。
让你的仓库做好准备
这些工作流在已经具备良好可读性的代码库上能走得更远——帮助 Bob 的事情,和帮助任何接手这段代码的工程师的事情,是同一件事:
- 一个绿色且足够快的构建。 这里的每个循环都锚定于编译和测试输出。你的
mvn/gradle构建越快越可靠,生成-运行-修复的循环就越紧。 - 已有的测试,哪怕是部分的。 覆盖率既是升级的安全网,也是 Bob 读取的信号。如果覆盖率不足,先从能力 4 开始,再尝试版本跳跃。
- 固定的、声明的依赖树。
pom.xml/build.gradle中明确的版本和最新的依赖锁文件,决定了是一次干净的规则运行,还是数天的冲突排查。 - Bob 可以驱动的构建工具。 Liberty 和安全工作流依赖标准插件(
liberty-maven-plugin、dependency-check、SBOM 工具);将它们配置好,自动化的那一半才能完成自己的工作。
如何获取访问权限
Premium Package for Java 是 Bob 基础计划的附加包,而不是单独的下载。
如何获得授权取决于你的计划:
- 个人计划(Pro、Pro+、Ultra)。 前往 bob.ibm.com 的定价页面,选择计划并在结账时添加 Java 附加包。完成订单并安装 Bob IDE 后,登录时会自动检测授权。在 bob.ibm.com 的订阅中管理席位和附加包。
- 企业计划。 你的 Bob 管理员通过 Bob Admin UI 分配基础计划席位和 Java 附加包。一旦席位分配给你,同样的自动检测就会生效——登录后工作流即会显示。
两件值得明确说明的事:
- 结账时必须选择 Java 附加包。 它默认不包含在基础计划中。如果在购买时跳过,即使在付费计划下,工作流也不会出现。
- 试用计划无法使用附加包。 Premium Package for Java 需要付费的 Pro、Pro+、Ultra 或企业计划。
开始使用
当你的计划包含附加包且已登录 Bob IDE:
- 先在单个模块上运行 JDK 升级评估,在确定目标之前查看建议的路径和难度评级。
- 如果覆盖率不足,先生成一份
UNITTEST.md策略,建立安全网,再进行任何版本跳跃。 - 逐模块审批变更——护栏的存在正是为了让命名空间和依赖变更始终在你的掌控之中。
在 bob.ibm.com 查看案例研究,了解各团队是如何端到端地完成这些迁移的。
