保护 JavaFX 应用

普通 Java 应用和 Spring Boot 桌面应用都可以启用 JavaFX。P4JX 的精简运行时默认不包含 JavaFX,需要在打包时显式启用,或者由兼容性扫描替你启用。

1. GUI 操作

  1. 普通 JavaFX 应用在应用类型页面选择 Java 应用;基于 Spring 容器的 JavaFX 桌面应用选择 Spring Boot类库加密只生成受保护归档,不能代替真正的 JavaFX 应用打包。

    选择 Java 应用或 Spring Boot

  2. 选择输入 JAR、随包 Java 版本和目标平台,然后选择简单模式或高级模式。JavaFX 组件按每个目标 Java 版本和平台分别获取,因此多平台任务会生成相互独立的输出包。

    选择输入、Java 版本、目标平台和模式

  3. 使用简单模式时,兼容性扫描如果发现 javafx.* 引用或 JavaFX 依赖,会自动启用 JavaFX,并在扫描结果中说明原因;如果同时发现 javafx.scene.web,还会一并包含 WebView。扫描属于静态启发式分析,进入输出页后仍应复核 JavaFX 摘要。

  4. 使用高级模式时,在 JavaFX 运行时页签中勾选将 JavaFX 内置到打包运行时,再选择 WebView 策略:

    • 自动(检测 javafx.scene.web):根据应用是否引用 javafx.scene.web 决定;
    • 包含:始终包含 WebView(fx-webkit);
    • 排除:始终不包含 WebView。

    普通 Java 应用的入口如下:

    在普通 Java 应用的高级参数中选择 JavaFX 运行时

    Spring Boot 桌面应用使用同名页签:

    在 Spring Boot 的高级参数中选择 JavaFX 运行时

  5. 选择输出目录后,确认参数摘要中 JavaFX 显示为已内置、WebView 状态符合预期,再点击运行保护。生成完成后,使用包内的启动脚本,在每个目标平台上验证窗口、FXML、CSS 与图片资源以及 WebView。

WebView 组件大约 40 MB,用不到时可以选择排除以缩小包体。高级页面中其它设置的含义,见 Protector4J 高级模式设置

2. 用 CLI 在线获取组件

p4j javaapp fx-app.jar dist --javafx

Spring Boot 搭配 JavaFX:

p4j springboot fx-boot.jar dist --javafx

强制包含或排除 WebView:

--javafx-webview
--no-javafx-webview

工具会根据目标 JDK 训练线和平台,从当前区域的公开下载站点取得对应组件。JavaFX 下载和 VLX JRE 下载都不需要把云存储密钥交给客户端。

3. 离线组件

CLI 支持指定本地目录:

p4j javaapp fx-app.jar dist --javafx /opt/p4jx-fx

该目录可以是以下两种形式之一:

  • fx-core.tar.gz 以及可选的 fx-webkit.tar.gz;或
  • 已经展开、以 lib/ 为根的 JavaFX 文件树。

GUI 不提供选择本地 JavaFX 目录的选项,离线场景请使用 CLI。

4. FXML

如果应用使用 FXMLLoader,兼容性扫描会建议开启扫描器 ZIP 覆盖层:

p4j javaapp fx-app.jar dist --javafx --zip-overlay scanner

FXML 资源、控制器签名和框架扫描,都需要在目标平台上实际启动应用来验证。

5. Java 8 与 Java 11 及以上

  • Java 8 使用 jfxrt.jar 和扩展目录模型,生成的脚本通常不需要模块参数。
  • Java 11 及以上使用模块化的 JavaFX JAR,生成的脚本会自动设置专用的模块路径和 --add-modules

请始终通过生成的 run.shrun.commandrun.bat 启动,不要自行把整个 vlxjre/lib 当作模块路径。

6. 自动检测的判断依据

检测器会检查你自己代码中的类引用,以及依赖 JAR 的文件名。它有意不去深入扫描每一个第三方依赖的字节码,否则会把仅仅可选的 JavaFX 集成误判为实际使用。

如果 JavaFX 被 shade 进了一个从名称看不出来的依赖中,自动检测可能漏报,这时请显式传入 --javafx

7. 保护范围建议

  • JavaFX Application 子类、FXML 控制器和属性模型是否保护,应以目标 Java 版本上的实测结果为准。
  • 由 JNI 或原生代码直接访问的桥接类应保持不受保护。
  • 先用简单模式或 --compat-scan,再针对窗口创建、FXML 加载、CSS 与图片资源、WebView 以及平台原生库做回归测试。