CheerpJ 5.0 发布:浏览器中运行 Java 21/25,完整 OpenJDK 与全新 WasmGC 引擎
我们很自豪地发布 CheerpJ 5.0,这是 CheerpJ 的最新主要版本。CheerpJ 是一个面向浏览器、以 WebAssembly 形式提供的完整 OpenJDK 发行版,旨在让 Java 应用和库在浏览器中运行。
此版本带来了无数改进,其中最受关注的是对 Java 21 和 25 的支持。加上 CheerpJ 已支持的 Java 8、11 和 17,这完成了我们于 2025 年 2 月首次发布的路线图;该路线图的目标是在 2026 年底前与最新 Java LTS 对齐。CheerpJ 5.0 现在还为每个受支持的版本提供完整 JDK,而不仅是 JRE,使得不仅可以在浏览器中运行现代 Java,还可以编译现代 Java。
但是,听起来可能有些奇怪,现代 Java 并不是此版本中最令人印象深刻的技术成就。CheerpJ 5.0 还包括对基于 WasmGC 的全新执行引擎的实验性支持。稳定该引擎将是我们未来几个月的重点,并将在 2027 年初随 CheerpJ 6.0 达到生产就绪。我们预计 WasmGC 引擎与其他若干工作方向一起,将使在浏览器中运行大规模现代 Java 应用变得切实可行,包括现代版本的 Minecraft 和 IntelliJ IDEA。
CheerpJ 如何工作?
[LOADING...] CheerpJ 架构图,展示主要组件。
CheerpJ 是一个完整的 WebAssembly JVM,于 2017 年首次发布,并从零开始设计,使 Java 成为浏览器中的一等语言。其当前架构随 2024 年 CheerpJ 3.0 引入,围绕一个编译为 WebAssembly 的 JIT 编译器重建。这使我们能够移除预处理步骤,并大幅提高与真实代码的兼容性。
与其他方案不同,CheerpJ 并不局限于专门为浏览器编写的 Java 代码。从第一天起,它就设计为无需修改即可运行现有的大规模 Java 应用程序。这意味着完整支持反射、运行时类生成、自定义类加载器、多线程和同步。CheerpJ 完全在 Java 字节码层面工作,因此永远不需要源代码。源代码不可用的专有或旧版应用也可使用 CheerpJ,经过混淆的 JAR 同样可以。而且由于 CheerpJ 运行字节码,任何 JVM 语言(包括 Kotlin 和 Scala)都可开箱即用。
除 JVM 本身之外,CheerpJ 还对浏览器原生不提供的能力提供广泛模拟,包括多个虚拟文件系统、网络、剪贴板集成、音频、打印和窗口管理。在某些方面,CheerpJ 甚至超越了原生 JVM 的能力:Java 桌面应用可以在手机和平板电脑上运行,并支持触摸输入,即使原始代码从未打算用于此类设备。
从总体上看,CheerpJ 由三个构建块组成:
-
JVM 和 JIT 编译器,用 C++ 编写并编译为 WebAssembly。代码从解释器开始执行,热点代码会被 JIT 编译,并进行内联和去虚拟化等优化。在默认引擎中,JIT 生成 JavaScript。在新的实验性 WasmGC 引擎中(见下文),它生成 WebAssembly。
-
每个受支持 Java 版本的完整且未修改的 OpenJDK 构建。所有内容都从未修改的源代码编译而来,包括整个被编译为 WebAssembly 的 JNI 层。
-
虚拟化系统层,包含文件系统(通过 HTTP 提供资源、IndexedDB 中的持久本地存储、由 JavaScript 提供的数据)、通过 Tailscale 的网络、剪贴板集成,以及支持同一页面上多个 Java 窗口和应用程序的窗口管理器。
如需更仔细地了解设计,请参阅我们在发布 CheerpJ 3.0 时发布的深度解析,以及文档中的架构页面。
CheerpJ 5.0 新特性
此版本包含超过六个月的工作,覆盖 CheerpJ 的每个组件。以下是变更摘要。
支持现代 Java(最高到 Java 25)
在浏览器中运行现代、大规模 Java 应用如今已成为现实。CheerpJ 在保留对遗留业务关键应用的访问方面非常成功,尤其是 Oracle Forms 和 E-Business Suite,相关工作仍在继续。借助 CheerpJ 5.0,我们在这一成功基础上继续发展,使 CheerpJ 也成为现代开发者工具:实际上,是一个拥有完整 OpenJDK 运行时、以浏览器为平台的替代 JVM。
完整 JDK,而不仅是 JRE
CheerpJ 一直只发布 OpenJDK 的 JRE 包,以减小下载体积和初始化时间。经过近期对 I/O 逻辑的优化工作,我们现在可以为每个受支持的 Java 版本放心地发布完整 JDK。这使得不仅可以在浏览器中运行 Java,还可以编译 Java:javac 和 jshell 现在都能在客户端运行。这开辟了全新用例范围,尤其是在教育领域。
对 WasmGC 的实验性支持
这无疑是自 CheerpJ 3.0 引入 JIT 架构以来最大的一次重构。我们构建了一个新的、快得多的解释器,以及第二个完全基于如今标准化的 WebAssembly GC 扩展运行的 JIT 后端。
在默认引擎中,Java 对象是 JavaScript 对象,热点代码被编译为 JavaScript。在 WasmGC 引擎中,Java 对象变成 WasmGC 对象,热点代码被编译为 WebAssembly。内存仍由浏览器的垃圾回收器管理。我们预计这将在启动和运行时带来相比当前稳定引擎的显著性能提升。
额外的好处是,WasmGC 简化了与本身编译为 Wasm 的复杂原生(JNI)库的交互。例如,这对 CheerpJ 对 LWJGL 的支持很重要,LWJGL 是 Minecraft 和许多其他 Java 游戏的基础构建块。CheerpJ 目前支持 LWJGL 2。运行 LWJGL 3 曾经可行,但性能开销很大,因而不切实际。我们预计 WasmGC 引擎将完全绕过这些问题,为现代 Minecraft 和许多其他基于 Java 的游戏铺平道路。
尽管令人兴奋,WasmGC 引擎仍是实验性的,现阶段仍不稳定。我们预计真实世界应用目前还无法使用它,但我们欢迎社区尽早测试。它需要手动启用:
WasmGC 引擎需要较新的浏览器:Chrome 和 Edge 137 或更高版本、Firefox 153 或更高版本、Safari 27 或更高版本(移动端为 iOS 和 iPadOS 27)。目前尚不会自动回退到默认引擎,因此请不要在生产环境中启用。稳定的 WasmGC 引擎是 CheerpJ 6.0 的重点,计划于 2027 年初发布。
许多其他错误修复和改进
除上述主要新特性外,此版本还修复了多个错误,增加了易用性改进,并进一步优化了启动和运行时性能。
稳定对 Java 11 和 17 的支持: 得益于社区和客户的测试,我们现在确信 CheerpJ 可以开箱即用地处理大多数 Java 11 和 Java 17 应用。
总体性能改进: 除 WasmGC 相关工作外,CheerpJ 5.0 在使用稳定引擎时也带来了多项性能改进。类文件解析速度加快,JIT 引擎已从基本原理出发完全重新调优,JAR 下载也已优化。
UI 与移动端支持: 对拖放和剪贴板集成进行了多项改进,进一步提高跨浏览器兼容性,并针对移动端支持进行了多项额外修复;移动端支持最初在上一版 CheerpJ 4.3 发布 中引入。
使用 CheerpJ 可以运行什么?
简而言之,CheerpJ 可以在浏览器中无需修改地运行大规模、现代 Java 桌面应用。我们相信演示胜过千言万语,因此为你挑选了几个用例。
大型 Swing 应用,包括自定义 Look & Feel
CheerpJ 完全支持基于 Swing 和 AWT 的 GUI 应用,包括使用自定义 Look & Feel 的情况。多窗口、剪贴板集成和打印也可正常工作。大多数情况下,应用的渲染效果与传统桌面 JVM 上完全相同。
此处展示的是来自流行 Look and Feel 库的 FlatLaf Demo,正在你的浏览器中实时运行。
使用 CheerpJ 在浏览器中运行的 FlatLaf Look and Feel 演示
目前不支持 JavaFX 和 SWT 应用,但这些工具包已列入我们的路线图。如果你的应用依赖它们,请联系我们:我们或许能够分享早期预览。
演示:浏览器中未经修改的 Minecraft
Browsercraft 是我们基于 Web 的“嵌入”历史 Java 版 Minecraft 的项目,它仍然是 CheerpJ 最严苛的压力测试之一。与你可能见过的其他方案不同,Browsercraft 并非基于反编译或逆向工程。原始 client.jar 直接从 Mojang 的服务器获取,并在浏览器中完全未经修改地运行。如果你还没试过,它仍然是展示 CheerpJ 能力的最佳案例之一。
观看 Browsercraft 在浏览器中运行。
我们将 Minecraft 视为我们技术的关键基准,并相信对现代 Java 的支持(在此版本中)以及稳定的 WasmGC 引擎(计划随 CheerpJ 6.0 推出)将使现代版本(包括模组)能够在浏览器中运行。
直接从 JavaScript 使用 Java 逻辑
库模式(Library Mode) 使得可以使用基于 async/await 的自然语法从 JavaScript 使用 Java 库,并可直接访问 Java 方法、对象和数组。在此基础上,原生方法支持允许直接用 JavaScript 实现 Java 原生方法,类似于 JNI 在标准 Java 平台上的工作方式。这些特性共同实现了 Java 与浏览器之间此前根本不可能达到的互操作水平。
以下代码片段应能让你大致了解库模式的能力。该代码片段使用流行的 iText Java 库,在浏览器中完全客户端地生成 PDF。