Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: scijava/scijava-common
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: scijava/scijava-common
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: fix-macos-javafx-deadlock
Choose a head ref
Checking mergeability… Don’t worry, you can still create the pull request.
  • 1 commit
  • 1 file changed
  • 1 contributor

Commits on Feb 6, 2026

  1. Fix JavaFX + AWT EDT macOS deadlocks

    This commit "fixes" deadlocks on macOS where the AWT
    EDT and JavaFX threading models clash. On macOS, but
    not Windows or Linux, all GUI things happen with AppKit
    and the Cocoa event loop. Additionally on macOS only
    **one** event dispatch thread (EDT) is allowed per
    event loop which means that JavaFX and AWT effectively
    share the same thread resources. The specific case
    that this addresses is flimlib/flimj-ui#35. FLIMJ (i.e.
    flimj-ui) is a JavaFX application that needs to interact
    with AWT UI elements. Briefly when a user attempts to
    export images back to Fiji by clicking "Export", the
    application hangs both the plugin and Fiji in general.
    From *my* understanding this is what is happening:
    
    1. The user clicks "Export" which triggers a GUI event
       which ultimately gets run with `invokeAndWait()` which
       is a blocking call until the export function returns.
       Because the event is tied to the GUI, the JavaFX now
       has a lock on the Cocoa event loop until export is complete.
    2. What the "Export" button does is show the selected images
       in Fiji, which means we need to use AWT now. The `show()` call
       is made and tiggers its necessary AWT code which ultimately
       asks for a lock on the Cocoa event loop to acess the GUI screen.
    3. The AWT thread never gets the Cocoa event loop because JavaFX has
       it and wont give it up until AWT shows the images and returns. But
       AWT **cant** becaues JavaFX has the lock. This is our threading
       dead lock and also why we see hangs here in the thread dumps:
    
       at sun.awt.CGraphicsDevice.nativeGetScreenInsets (Native Method)
       at org.scijava.thread.DefaultThreadService.invoke (line 114)
    
    This doesn't happen on Windows or Linux becauase, according
    to the bug discussion linked below, its possible to have
    more than one EDT on those systems. Just not macOS. What this commit
    does is instead of using the blocking `invoke()` call via the ThreadService
    which gets us in this trouble, we instead detect a JavaFX thread and
    do an async queue instead. This means that JavaFX doesn't lock the
    Cocoa event loop, apperently, and AWT is safe to do its thing and return.
    
    See https://bugs.openjdk.org/browse/JDK-8087465 for
    more details on this JavaFX + AWT bug.
    elevans committed Feb 6, 2026
    1 Configuration menu
    Copy the full SHA
    0d4b5dc View commit details
    Browse the repository at this point in the history
Loading