Skip to content

Sporadic deadlock during test_getLAFList #1445

Closed

Description

@ptziegler

See https://github.com/eclipse-windowbuilder/windowbuilder/actions/runs/24211792675/job/70682186432

I finally managed to reproduce this problem locally! The problem itself appears since #1230, because the "new" OSSupportLinux class no longer uses the gdkThreadsEnter() and gdkThreadsLeave() methods (because we really shouldn't use them). Here the thread dump of the SWT UI and the AWT Event Dispatcher thread:

"main" #3 [13658] prio=6 os_prio=0 cpu=3678,19ms elapsed=463,93s tid=0x0000777f0002b140 nid=13658 in Object.wait()  [0x0000777f065fa000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait0(java.base@24.0.2/Native Method)
        - waiting on <no object reference available>
        at java.lang.Object.wait(java.base@24.0.2/Object.java:389)
        at java.lang.Object.wait(java.base@24.0.2/Object.java:351)
        at java.awt.EventQueue.invokeAndWait(java.desktop@24.0.2/EventQueue.java:1306)
        - locked <0x0000000632fff490> (a java.awt.EventQueue$1AWTInvocationLock)
        at java.awt.EventQueue.invokeAndWait(java.desktop@24.0.2/EventQueue.java:1287)
        at org.eclipse.wb.os.OSSupport.runAwt(OSSupport.java:417)
        at org.eclipse.wb.internal.swing.utils.SwingUtils.invokeLaterAndWait(SwingUtils.java:212)
        at org.eclipse.wb.internal.swing.utils.SwingUtils.runLaterAndWait(SwingUtils.java:113)
        at org.eclipse.wb.internal.swing.utils.SwingUtils.clearSwingTree(SwingUtils.java:283)
        at org.eclipse.wb.internal.swing.model.component.ContainerInfo.refresh_dispose(ContainerInfo.java:260)
        at org.eclipse.wb.internal.core.parser.JavaInfoParser.disposeComponentsHierarchy(JavaInfoParser.java:352)
        at org.eclipse.wb.internal.core.parser.JavaInfoParser.getRoot(JavaInfoParser.java:429)
        at org.eclipse.wb.internal.core.parser.JavaInfoParser.parseRootMethods(JavaInfoParser.java:321)
        at org.eclipse.wb.internal.core.parser.JavaInfoParser.parse(JavaInfoParser.java:267)
        at org.eclipse.wb.internal.core.parser.JavaInfoParser.lambda$0(JavaInfoParser.java:150)
        at org.eclipse.wb.internal.core.parser.JavaInfoParser$$Lambda/0x0000777e877fcdb0.call(Unknown Source)
        at org.eclipse.wb.internal.core.utils.execution.ExecutionUtils.runDesignTime(ExecutionUtils.java:159)
        at org.eclipse.wb.internal.core.parser.JavaInfoParser.parse(JavaInfoParser.java:150)
        at org.eclipse.wb.tests.designer.core.model.parser.AbstractJavaInfoTest.parseCompilationUnit(AbstractJavaInfoTest.java:465)
        at org.eclipse.wb.tests.designer.core.model.parser.AbstractJavaInfoTest.parseSource(AbstractJavaInfoTest.java:446)
        at org.eclipse.wb.tests.designer.swing.SwingModelTest.parseJavaInfo(SwingModelTest.java:74)
        at org.eclipse.wb.tests.designer.swing.SwingModelTest.parseContainer(SwingModelTest.java:78)
        at org.eclipse.wb.tests.designer.swing.laf.LookAndFeelTest.test_addSetLookAndFeel(LookAndFeelTest.java:154)
        ...

   Locked ownable synchronizers:
        - None

"AWT-EventQueue-0" #94 [13775] prio=6 os_prio=0 cpu=65,32ms elapsed=459,96s tid=0x0000777f01faba80 nid=13775 runnable  [0x0000777dada79000]
   java.lang.Thread.State: RUNNABLE
        at com.sun.java.swing.plaf.gtk.GTKEngine.native_get_gtk_setting(java.desktop@24.0.2/Native Method)
        at com.sun.java.swing.plaf.gtk.GTKEngine.getSetting(java.desktop@24.0.2/GTKEngine.java:634)
        - locked <0x000000061c9131a8> (a java.lang.Object)
        at com.sun.java.swing.plaf.gtk.GTKLookAndFeel.getGTKStyleFactory(java.desktop@24.0.2/GTKLookAndFeel.java:1580)
        at com.sun.java.swing.plaf.gtk.GTKLookAndFeel.loadStyles(java.desktop@24.0.2/GTKLookAndFeel.java:1566)
        at com.sun.java.swing.plaf.gtk.GTKLookAndFeel.initialize(java.desktop@24.0.2/GTKLookAndFeel.java:1442)
        at javax.swing.UIManager.setLookAndFeel(java.desktop@24.0.2/UIManager.java:583)
        at javax.swing.UIManager.setLookAndFeel(java.desktop@24.0.2/UIManager.java:630)
        at org.eclipse.wb.internal.swing.laf.model.LafInfo.getLookAndFeelInstance(LafInfo.java:111)
        at org.eclipse.wb.tests.designer.swing.laf.LookAndFeelTest.lambda$1(LookAndFeelTest.java:430)
        at org.eclipse.wb.tests.designer.swing.laf.LookAndFeelTest$$Lambda/0x0000777e875c18c8.run(Unknown Source)
        at org.eclipse.wb.internal.core.utils.execution.ExecutionUtils.runLog(ExecutionUtils.java:106)
        at org.eclipse.wb.internal.swing.utils.SwingUtils.lambda$1(SwingUtils.java:76)
        at org.eclipse.wb.internal.swing.utils.SwingUtils$$Lambda/0x0000777e879d9c98.run(Unknown Source)
        at java.util.concurrent.CompletableFuture$AsyncRun.run(java.base@24.0.2/CompletableFuture.java:1850)
        at java.awt.event.InvocationEvent.dispatch(java.desktop@24.0.2/InvocationEvent.java:318)
        at java.awt.EventQueue.dispatchEventImpl(java.desktop@24.0.2/EventQueue.java:723)
        at java.awt.EventQueue.dispatchEvent(java.desktop@24.0.2/EventQueue.java:702)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(java.desktop@24.0.2/EventDispatchThread.java:203)
        at java.awt.EventDispatchThread.pumpEventsForFilter(java.desktop@24.0.2/EventDispatchThread.java:124)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(java.desktop@24.0.2/EventDispatchThread.java:113)
        at java.awt.EventDispatchThread.pumpEvents(java.desktop@24.0.2/EventDispatchThread.java:109)
        at java.awt.EventDispatchThread.pumpEvents(java.desktop@24.0.2/EventDispatchThread.java:101)
        at java.awt.EventDispatchThread.run(java.desktop@24.0.2/EventDispatchThread.java:90)

   Locked ownable synchronizers:
        - None

It's the same problem we had in the past; Updating the Swing LookAndFeel requires an exclusive UI lock, meaning that it can't be done while the SWT UI thread holds at least a partial lock. So if this update is initiated from the SWT UI thread and if it is done as a blocking operation, this operation will never be able to complete.

Activity

  1. added theissue type on Apr 10, 2026
  2. ptziegler commented on Apr 10, 2026

    @ptziegler
    ContributorAuthor

    The clearSwingTree() method mentions a memory leak reported in https://bugreport.java.com/bugdatabase/JDK-6407026 and https://bugs.eclipse.org/bugs/show_bug.cgi?id=127374. This method doesn't actually solve the leak. It only tries to minimize it. But according to the Oracle bug, this problem was fixed back in 2011, so perhaps we don't actually need it anymore... At the very least this cleanup operation can be done asynchronously and/or limited to Windows.

  3. ptziegler commented on Apr 10, 2026

    @ptziegler
    ContributorAuthor

    I've executed the following snippet (which was attached to the Oracle bug) and can't detect any memory leak. This seems to confirm that the underlying problem has been fixed.

    import java.awt.*;
    
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JTextField;
    
    import org.eclipse.swt.internal.win32.*;
    //import org.eclipse.swt.widgets.Display;
    
    /**
     * @author scheglov_ke
     */
    public class PR127374 {
            /**
             * @param args
             */
            public static void main(String[] args) throws Exception {
                    //Display display = new Display();
                            OS.OleInitialize(0);
                    //
                    for (int i = 0; i < 100; i++) {
                        System.out.println(i);
                        JFrame frame = new JFrame();
                        //
                        JTextField textField = new JTextField();
                        frame.getContentPane().add(textField, BorderLayout.NORTH);
                        //
                        JLabel label = new JLabel(getBigString());
                        frame.getContentPane().add(label, BorderLayout.SOUTH);
                        //
                        frame.setVisible(true);
                        frame.setVisible(false);
                        //frame.getContentPane().remove(textField); //un-comment this line to remove leak
                        frame.dispose();
                        //
                        PR127374.printMemory();
                    }
                    OS.OleUninitialize();
                    //display.dispose();
                    //
                    Thread.sleep(100000);
            }
            private static void printMemory() {
                    System.gc();
                    System.out.println(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
            }
            private static String getBigString() {
                    int size = 1024 * 1024;
                    StringBuffer sb = new StringBuffer(size);
                    for (int i = 0; i < size; i++) {
                            sb.append('*');
                    }
                    return sb.toString();
            }
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions