跳到主要内容

JEP 283:在 Linux 上启用 GTK 3

概括

使 Java 图形应用程序(无论是基于 JavaFX、Swing 还是 AWT)能够在 Linux 上使用 GTK 2 或 GTK 3。

目标

  • 默认支持原生 GTK 2,并可故障转发至 GTK 3。
  • 当系统属性指示时使用 GTK 3。
  • 如果需要 GTK 3 来实现互操作性,并且可以尽早检测到此要求,请自动启用 GTK 3。
  • 允许现有应用程序未经修改地在安装了 GTK 2 或 GTK 3 之一或两者的 Linux 系统上运行。

非目标

在 AWT/Swing 和 JavaFX 之间共享动态包装器机制。

动机

Linux 上的 Java 目前使用 GTK 2。这引发了几个问题:

  • 有许多使用 GTK 的 Java 包。其中包括 AWT/Swing、JavaFX 和 SWT。 SWT 已迁移到 GTK 3,但有一个系统属性可用于强制它使用旧版本。使用不同 GTK 版本的包混合会导致应用程序失败。对于基于 SWT 的 Eclipse,这个问题尤其明显。 JavaFX 可以与 Swing 或 SWT 共存。

  • 版本可用性:GTK 3 于 2011 年发布,是活跃的开发流。虽然版本 2 和版本 3 在当前常见的 Linux 发行版上默认可用,但在 JDK 9 的生命周期中可能不会继续出现这种情况。

  • SWT 的更高版本可能会放弃 GTK 2 后备支持标志。

  • 一些应用程序(例如,Java Mission Control)混合了 JavaFX 和 SWT,并依赖于 GTK 2 后备支持标志。

描述

Java 图形应该能够支持 GTK 2 和 GTK 3。

AWT 和 Swing 当前使用动态查找所需的 GTK 函数,而不是直接与本机库本身链接。

JavaFX在其他领域也采用了类似的机制,并且在调用GTK时可以在窗口管理代码中采用类似的机制。

这种动态加载机制可以扩展为选择 GTK 2 或 3,通过包装函数尽可能隐藏任何显着的编程差异。可能会有一些程序性问题需要解决;例如,数据结构的差异或功能的不同。

系统属性将用于影响运行时 GTK 2 或 3 的选择。默认情况下,该属性将指示 GTK 2 以降低风险。如果系统上不存在 GTK 2,则运行时将自动选择 GTK 3。如果运行时能够及时检测到需要使用 GTK 3,例如FXCanvas与 SWT 一起使用时,则系统属性将自动设置到 GTK 3。

JavaFX 通过 与 AWT/Swing 交互JFXPanel,并使用 AWT 功能来支持打印。可以在 JavaFX 中仅实现 GTK 2/3 支持,但这会限制可支持的应用程序类型。

AWT/Swing 的主要子任务:

  • 调整现有的动态 GTK shim 以支持 GTK 3。
  • 重新设计 Swing GTK LnF 以支持 GTK-3。
  • 将对等点迁移FileChooserDialog到 GTK-3。
  • 迁移AwtRobot到 GTK-3(或者删除对任何 GTK 的依赖)。
  • 通过现有的自动化测试(GTK 2 和 GTK 3)进行测试。

JavaFX 的子任务:

  • 创建一个 shim 来动态加载 GTK 2。
  • 调整动态 GTK shim 以支持 GTK 3。
  • 通过现有的自动化测试(GTK2 和 GTK 3)进行测试。

备择方案

迁移 Java 图形以仅支持 GTK 3。

优点:

  • 将现有代码迁移到 GTK3 进行编译和使用的移植和测试总体工作量较少。
  • 只有一条测试路径而不是两条。
  • 只有一条代码路径向前推进。

缺点:

  • 我们的测试未检测到错误的风险较高。
  • AWT 外观和感觉的额外努力。
  • 需要(有点不可能)在目标系统上安装 GTK 3 二进制文件。
  • 需要同时移植 JavaFX 和 AWT/Swing,或者都不移植;没有机会放弃其中一个子项目而仍然交付另一个子项目。
  • 移植需要 AWT 和 Swing 之间更大程度的协调。

测试

应使用 Linux 上 Java 的现有系统测试。

至少,应在一次或多次测试运行中使用(强制)非默认路径 (GTK 3),以验证所有通过的测试是否继续通过。

风险和假设

所提出的解决方案的主要风险是会引入新的错误,而这些错误不会被测试发现。 AWT 使用更多功能,因此由于 GTK 行为变化而添加新错误的风险可能更高。

由于不可预见的技术困难,AWT/Swing 子任务或 JavaFX 子任务存在无法及时完成的风险。

如果 AWT/Swing 无法完成,那么这将对 JavaFX 造成运行时限制,但仅限于混合两者的应用程序。这主要是使用JFXPanel或执行打印的应用程序。

如果 JavaFX 无法完成,那么混合 JavaFX 和 SWT 的应用程序将会出现运行时问题 ( FXCanvas)。