<div dir="ltr"><div dir="ltr"><div>Hi Laurent,</div><div><br></div><div>Thanks for your test! Great job :-)</div><div><br></div><div>I applied some minor changes for integration:</div><div><br></div><div> * Renamed to TestSeqEventsMultipleContexts</div><div>  * A bit longer but should describe what this is about</div><div>  * Placed in jdk/java/awt/event/SequencedEvent</div><div><br></div><div> * Encapsulated the window in TestWindow class</div><div><br></div><div> * Instead of waiting 1s for windows to show, loop until windows are shown -or the test hard stops-. When I ran in my environment, 1s was not enough. This should make the test more resilent. We still depend on a timer but that is inevitably.</div><div><br></div><div> * Incremented the time we wait for the TGs to finish. 2s was not enough in my runs. However, we now do frequent checks to finish earlier in the success path.</div><div><br></div><div> * Calculated expected value in initilization time</div><div><br></div><div> * Changed a bit how the test finishes</div><div>  * System.exit(0) is a failure for jtreg</div><div>  * We need status -1 for jtreg to detect failures, and will do a hard stop when time expires</div><div>  * Stack traces for the main thread are not much relevant </div><div>  * dispose window to exit gracefully on the success path</div><div><br></div><div> * Removed unused code (button click action)</div><div><br></div><div> * Added jtreg tags & copyright</div><div><br></div><div>Webrev.02 with test integrated:</div><div><br></div><div> * <a href="http://cr.openjdk.java.net/~mbalao/webrevs/8204142/8204142.webrev.02">http://cr.openjdk.java.net/~mbalao/webrevs/8204142/8204142.webrev.02</a></div><div> * <a href="http://cr.openjdk.java.net/~mbalao/webrevs/8204142/8204142.webrev.02.zip">http://cr.openjdk.java.net/~mbalao/webrevs/8204142/8204142.webrev.02.zip</a></div><div><br></div><div>Kind regards,</div><div>Martin.-</div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Oct 15, 2018 at 3:38 PM, Laurent Bourgès <span dir="ltr"><<a href="mailto:bourges.laurent@gmail.com" target="_blank">bourges.laurent@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div dir="ltr">Hi Martin,<br><div><div class="gmail_quote"><span class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div>Thanks for your feedback and happy to hear that it worked!</div><div><br></div><div>In regards to <span style="font-size:12.8px">pendingEvents sync, my understanding is that SequencedEvent objects will be posted to one EventQueue only and, thus, be dispatched by one EDT.</span></div></div></div></div></div></div></div></div></div></blockquote><div><br></div></span><div>Agreed. <br></div><span class=""><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">I had a quick look at "Exception in thread "AWT-EventQueue-1" java.lang.<wbr>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_<wbr>FOCUS" case is null (DefaultKeyboardFocusManager.<wbr>dispatchEvent function</span><span style="font-size:12.8px">). 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 </span><span style="font-size:12.8px">DefaultKeyboardFocusManag<wbr>er dispatches the event, it could be too late. Just an hypothesis.</span></div></div></div></div></div></div></div></div></div></blockquote><div><br></div></span><div>I agree, it is certainly a side-effect: other issues may be triggered by such event intensive test.<br></div><span class=""><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div><span style="font-size:12.8px"></span></div><div><span style="font-size:12.8px">Look forward to your re-written test.</span></div></div></div></div></div></div></div></div></div></blockquote><div><br></div></span><div>Here it is:</div><div><span style="font-family:monospace,monospace"><br>import java.awt.BorderLayout;<br>import java.awt.Dimension;<br>import java.awt.event.ActionEvent;<br>import java.awt.event.ActionListener;<br>import java.util.ArrayList;<br>import java.util.List;<br>import java.util.concurrent.atomic.<wbr>AtomicReference;<span class=""><br>import javax.swing.JButton;<br><br>import javax.swing.JFrame;<br>import javax.swing.JLabel;<br>import javax.swing.SwingUtilities;<br>import javax.swing.Timer;<br><br></span><span class="">/*<br> * Running this code causes the AWT Event Queues to be blocked on OpenJDK11<br></span> * javac --add-exports java.desktop/sun.awt=ALL-<wbr>UNNAMED TestWinEvent.java<br> *<span class=""><br> * @author Laurent Bourges<br> */<br></span>public final class TestWinEvent extends JFrame implements ActionListener {<span class=""><br><br>    private static final long serialVersionUID = 1L;<br><br></span>    private static final int NUM_WINDOW = 2;<br>    private static final int INTERVAL = 50;<br>    private static final int MAX_TIME = 10000; // 10s<br>    private static final int MAX_COUNT = MAX_TIME / INTERVAL;<br>    private static final List<TestWinEvent> WINDOWS = new ArrayList<TestWinEvent>();<br><br>    private final JButton btn;<span class=""><br>    private int counter = 0;<br></span>    private final Timer t;<span class=""><br><br>    public static void main(String[] args) {<br></span>        try {<br>            for (int i = 0; i < NUM_WINDOW; i++) {<br>                createWin(i + 1);<br>            }<br><br>            // Wait MAX_TIME + 2s<br>            Thread.sleep(MAX_TIME + 2000);<br><br>            int total = 0;<br>            for (TestWinEvent window : WINDOWS) {<br>                total += window.getCounter();<br>            }<br><br>            // Failure if AWT hanging: assert<br>            final int expected = MAX_COUNT * NUM_WINDOW;<br>            if (total != expected) {<br>                throw new IllegalStateException("Total [" + total + "] != expected [" + expected + "] !");<br>            }<br>        } catch (InterruptedException ie) {<br>            ie.printStackTrace();<br>        } catch (IllegalStateException iae) {<br>            iae.printStackTrace();<br>        } finally {<br>            System.exit(0);<span class=""><br>        }<br>    }<br><br>    private static void createWin(int tgNum) {<br></span>        new Thread(new ThreadGroup("TG " + tgNum),<br>                new Runnable() {<br>            @Override<br>            public void run() {<br>                sun.awt.SunToolkit.<wbr>createNewAppContext();<br><br>                final AtomicReference<TestWinEvent> ref = new AtomicReference<TestWinEvent>(<wbr>);<br><br>                SwingUtilities.invokeLater(new Runnable() {<br>                    @Override<span class=""><br>                    public void run() {<br>                        final TestWinEvent window = new TestWinEvent(tgNum);<br>                        window.setVisible(true);<br></span>                        ref.set(window);<br>                        WINDOWS.add(window);<br>                    }<br>                });<br><br>                try {<br>                    // Wait 1s to show window<br>                    Thread.sleep(1000);<br>                } catch (InterruptedException ie) {<br>                    ie.printStackTrace();<br>                }<br><br>                final TestWinEvent window = ref.get();<br>                if (window != null) {<br>                    window.enableTimer(true);<br>                }<br>            }<br>        }).start();<br>    }<br><br>    TestWinEvent(final int num) {<br>        super("Test Window [" + num + "]");<span class=""><br>        setMinimumSize(new Dimension(300, 200));<br>        setLocation(100 + 400 * (num - 1), 100);<br><br>        setLayout(new BorderLayout());<br>        JLabel textBlock = new JLabel("Lorem ipsum dolor sit amet...");<br>        add(textBlock);<br><br>        btn = new JButton("TEST");<br>        btn.addActionListener(new ActionListener() {<br>            @Override<br>            public void actionPerformed(ActionEvent e) {<br>                System.out.println("Button#" + num + " clicked: " + counter);<br>            }<br><br>        });<br>        add(btn, BorderLayout.SOUTH);<br><br>        setDefaultCloseOperation(<wbr>JFrame.EXIT_ON_CLOSE);<br>        pack();<br><br></span>        t = new Timer(INTERVAL, this);<br>        t.setRepeats(false);<span class=""><br>    }<br><br>    @Override<br>    public void actionPerformed(ActionEvent e) {<br></span>        this.toFront();<br>        btn.setText("TEST " + (++counter));<br>        this.toBack();<br>        if (counter < MAX_COUNT) {<br>            enableTimer(true);<br>        } else {<br>            setVisible(false);<br>        }<br>    }<br><br>    void enableTimer(boolean enable) {<br>        if (enable) {<br>            t.start();<br>        } else {<br>            t.stop();<br>        }<br>    }<br><br>    int getCounter() {<br>        return counter;<br>    }<br>}</span><br></div><div><br></div><div>I will attach it in the JBS bug.</div><div><br></div><div>Regards,</div><div>Laurent</div></div></div></div></div>
</blockquote></div><br></div>