JEP 283: Enable GTK 3 on Linux
Summary
Enable Java graphical applications, whether based on JavaFX, Swing, or AWT, to use either GTK 2 or GTK 3 on Linux.
Goals
- Support native GTK 2 by default, with fail forward to GTK 3.
- Use GTK 3 when indicated by a system property.
- In cases where GTK 3 is required for interoperability, and this requirement can be detected sufficiently early, enable GTK 3 automatically.
- Allow existing applications to run unmodified on a Linux system with either or both of GTK 2 or GTK 3 installed.
Non-Goals
Share the dynamic wrapper mechanisms between AWT/Swing and JavaFX.
Motivation
Java on Linux currently uses GTK 2. This raises several issues:
-
There are a number of Java packages that use GTK. These include AWT/Swing, JavaFX, and SWT. SWT has migrated to GTK 3, though there is a system property that can be used to force it to use the older version. This mixing of packages using different GTK versions causes application failures. This issue is particularly noticeable with Eclipse, which is SWT based. JavaFX can coexist with either Swing or SWT.
-
Version availability: GTK 3 was released in 2011, and is the active development stream. While both version 2 and 3 are available by default on current common Linux distributions, this may not continue to be the case over the lifetime of JDK 9.
-
Later versions of SWT may drop the GTK 2 fallback support flag.
-
Some applications (e.g., Java Mission Control) mix JavaFX and SWT, and rely on the GTK 2 fallback support flag.
Description
Java graphics should be able to support both GTK 2 and GTK 3.
AWT and Swing currently use a dynamic lookup of the required GTK functions, instead of directly linking with the native libraries themselves.
JavaFX has employed a similar mechanism in other areas, and can employ a similar mechanism in the window management code when calling GTK.
This dynamic loading mechanism can be extended to select either GTK 2 or 3, hiding as much as possible, with wrapper functions, any significant programmatic differences. It is likely that there will be some programmatic issues that will need to be resolved; for example, differences in data structures, or different functions.
A system property will be used to influence the selection of GTK 2 or 3 at run time. By default, this property will indicate GTK 2 to reduce risk. If GTK 2 is not present on a system then the run time will automatically choose GTK 3. If the run time can detect the need to use GTK 3 in time, for example when FXCanvas
is used with SWT, then the system property will automatically be set to GTK 3.
JavaFX interacts with AWT/Swing via JFXPanel
, and uses AWT functionality for printing support. It is possible to implement just the GTK 2/3 support in JavaFX, but that will come with limitations on the types of applications that can be supported.
Major subtasks for AWT/Swing:
- Adapt the existing dynamic GTK shim to support GTK 3 as well.
- Rework Swing GTK LnF to support GTK-3.
- Migrate the
FileChooserDialog
peer to GTK-3. - Migrate
AwtRobot
to GTK-3 (or maybe remove dependency on any GTK). - Test via existing automated tests, both GTK 2 and GTK 3.
Subtasks for JavaFX:
- Create a shim to dynamically load GTK 2.
- Adapt the dynamic GTK shim to support GTK 3 as well.
- Test via existing automated tests, both GTK2 and GTK 3.
Alternatives
Migrate Java graphics to support only GTK 3.
Pros:
- Less overall effort in porting and testing to migrate the existing code to compile with and use GTK3.
- Only one testing path instead of two.
- Only one code path moving forward.
Cons:
- Higher risk of bugs not detected by our testing.
- Additional effort with AWT look and feel.
- The (somewhat unlikely) need for GTK 3 binaries to be installed on a target system.
- Would require both or neither of JavaFX and AWT/Swing to be ported; there would be no opportunity to drop one of the sub-projects and still deliver the other.
- Porting would require a greater degree of coordination between AWT and Swing.
Testing
The existing system tests for Java on Linux should be used.
At a minimum, the non-default path (GTK 3) should be used (forced) on one or more test runs to verify that all passing tests continue to pass.