On Mon, 26 Aug 2024 21:57:51 GMT, Andy Goryachev <ango...@openjdk.org> wrote:

>> A Swing / FX interop app will crash if an application creates a new AWT / 
>> Swing window after calling Platform.exit. The root cause of the crash is 
>> that AWT caches the JNI env pointer for the AppKit thread, and assumes that 
>> it is valid for the life of the application. In the case where JavaFX is the 
>> owner of the NSApplication, we detach the AppKit thread from the JVM, after 
>> which AWT's env pointer is no longer valid. AWT will therefore crash the 
>> next time it does a JNI upcall.
>> 
>> This PR fixes the crash by leaving the macOS AppKit thread attached to the 
>> JVM after the JavaFX main event loop terminates. This requires attaching the 
>> AppKit thread to the JVM as a daemon thread when JavaFX is the NSApplication 
>> owner, matching what AWT does when it is the owner. In order to prevent a 
>> JavaFX application from exiting prematurely, create a non-daemon "KeepAlive" 
>> thread that can be terminated when the FX toolkit exits. This also solves a 
>> somewhat-related problem where the JavaFX toolkit will exit prematurely if 
>> the AWT toolkit is started first, and all AWT windows are disposed.
>> 
>> This fix is in addition to the AWT fix: 
>> [JDK-8190329](https://bugs.openjdk.org/browse/JDK-8190329) / 
>> openjdk/jdk#20688. Either the AWT fix or the JavaFX fix is sufficient to 
>> avoid this specific problem, but there is value in fixing it in both places, 
>> so I cloned the AWT bug to create a JavaFX bug that we can use for this PR.
>> 
>> Summary of the changes:
>> 
>> * Attach the AppKit thread to the JVM as a daemon
>> * Do not detach the thread when the FX main event loop terminates
>> * Create and start a KeepAlive thread in MacApplication, when the FX toolkit 
>> starts
>> * Terminate the KeepAlive thread when the FX toolkit finishes
>> 
>> Testing:
>> 
>> I created automated systems tests from the manual test programs in the bugs 
>> as well as a test to ensure that we don't regress and exit prematurely in 
>> the pure JavaFX case (which would happen without the KeepAlive thread). Two 
>> of the new tests fail on macOS without the fix and pass with the fix. All 
>> three pass on all platforms with the fix.
>
> modules/javafx.graphics/src/main/java/com/sun/glass/ui/mac/MacApplication.java
>  line 81:
> 
>> 79:         thr.setName("JavaFX-KeepAlive");
>> 80:         thr.setDaemon(false);
>> 81:         thr.start();
> 
> is it possible to reuse some other thread for this purpose?
> this may not be an issue when virtual threads take hold, but right now 
> threads are precious native resource.

No. The whole reason we are doing this is that there are no other non-daemon 
threads. I updated the docs to make this more clear. Anyway, threads aren't 
_that_ scarce as long as you don't create hundreds of them.

Loosely related: This reminds me that `javafx.application.Application.launch` 
does create an unnecessary thread (on all platforms). There is a long-standing 
issue to get rid of it:

[JDK-8090323](https://bugs.openjdk.org/browse/JDK-8090323): Consider 
eliminating the JavaFX-Launcher Thread

It isn't high priority, but would be good cleanup.

-------------

PR Review Comment: https://git.openjdk.org/jfx/pull/1545#discussion_r1732997480

Reply via email to