<AWT Dev> OpenJdk11-28-EA JDialog hanging

Laurent Bourgès bourges.laurent at gmail.com
Mon Oct 15 13:38:09 UTC 2018


Hi Martin,

> Thanks for your feedback and happy to hear that it worked!
>
> In regards to pendingEvents sync, my understanding is that SequencedEvent
> objects will be posted to one EventQueue only and, thus, be dispatched by
> one EDT.
>

Agreed.


> I had a quick look at "Exception in thread "AWT-EventQueue-1"
> java.lang.IllegalArgumentException: null source" exception and could not
> find any connection to the code modified in the context of this bug.
> Apparently, "activeWindow" variable in "WindowEvent.WINDOW_LOST_FOCUS" case
> is null (DefaultKeyboardFocusManager.dispatchEvent function). I thought
> that this was caused by the fact that the test is injecting events that
> modify the focus on both windows at a very high rate and, by the time DefaultKeyboardFocusManager
> dispatches the event, it could be too late. Just an hypothesis.
>

I agree, it is certainly a side-effect: other issues may be triggered by
such event intensive test.


> Look forward to your re-written test.
>

Here it is:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import javax.swing.JButton;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

/*
 * Running this code causes the AWT Event Queues to be blocked on OpenJDK11
 * javac --add-exports java.desktop/sun.awt=ALL-UNNAMED TestWinEvent.java
 *
 * @author Laurent Bourges
 */
public final class TestWinEvent extends JFrame implements ActionListener {

    private static final long serialVersionUID = 1L;

    private static final int NUM_WINDOW = 2;
    private static final int INTERVAL = 50;
    private static final int MAX_TIME = 10000; // 10s
    private static final int MAX_COUNT = MAX_TIME / INTERVAL;
    private static final List<TestWinEvent> WINDOWS = new
ArrayList<TestWinEvent>();

    private final JButton btn;
    private int counter = 0;
    private final Timer t;

    public static void main(String[] args) {
        try {
            for (int i = 0; i < NUM_WINDOW; i++) {
                createWin(i + 1);
            }

            // Wait MAX_TIME + 2s
            Thread.sleep(MAX_TIME + 2000);

            int total = 0;
            for (TestWinEvent window : WINDOWS) {
                total += window.getCounter();
            }

            // Failure if AWT hanging: assert
            final int expected = MAX_COUNT * NUM_WINDOW;
            if (total != expected) {
                throw new IllegalStateException("Total [" + total + "] !=
expected [" + expected + "] !");
            }
        } catch (InterruptedException ie) {
            ie.printStackTrace();
        } catch (IllegalStateException iae) {
            iae.printStackTrace();
        } finally {
            System.exit(0);
        }
    }

    private static void createWin(int tgNum) {
        new Thread(new ThreadGroup("TG " + tgNum),
                new Runnable() {
            @Override
            public void run() {
                sun.awt.SunToolkit.createNewAppContext();

                final AtomicReference<TestWinEvent> ref = new
AtomicReference<TestWinEvent>();

                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        final TestWinEvent window = new TestWinEvent(tgNum);
                        window.setVisible(true);
                        ref.set(window);
                        WINDOWS.add(window);
                    }
                });

                try {
                    // Wait 1s to show window
                    Thread.sleep(1000);
                } catch (InterruptedException ie) {
                    ie.printStackTrace();
                }

                final TestWinEvent window = ref.get();
                if (window != null) {
                    window.enableTimer(true);
                }
            }
        }).start();
    }

    TestWinEvent(final int num) {
        super("Test Window [" + num + "]");
        setMinimumSize(new Dimension(300, 200));
        setLocation(100 + 400 * (num - 1), 100);

        setLayout(new BorderLayout());
        JLabel textBlock = new JLabel("Lorem ipsum dolor sit amet...");
        add(textBlock);

        btn = new JButton("TEST");
        btn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Button#" + num + " clicked: " +
counter);
            }

        });
        add(btn, BorderLayout.SOUTH);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();

        t = new Timer(INTERVAL, this);
        t.setRepeats(false);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        this.toFront();
        btn.setText("TEST " + (++counter));
        this.toBack();
        if (counter < MAX_COUNT) {
            enableTimer(true);
        } else {
            setVisible(false);
        }
    }

    void enableTimer(boolean enable) {
        if (enable) {
            t.start();
        } else {
            t.stop();
        }
    }

    int getCounter() {
        return counter;
    }
}

I will attach it in the JBS bug.

Regards,
Laurent
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/awt-dev/attachments/20181015/e88e6613/attachment.html>


More information about the awt-dev mailing list