<AWT Dev> OpenJdk11-28-EA JDialog hanging

Martin Balao mbalao at redhat.com
Tue Oct 16 11:48:17 UTC 2018


Hi Laurent,

Thanks for your test! Great job :-)

I applied some minor changes for integration:

 * Renamed to TestSeqEventsMultipleContexts
  * A bit longer but should describe what this is about
  * Placed in jdk/java/awt/event/SequencedEvent

 * Encapsulated the window in TestWindow class

 * 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.

 * 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.

 * Calculated expected value in initilization time

 * Changed a bit how the test finishes
  * System.exit(0) is a failure for jtreg
  * We need status -1 for jtreg to detect failures, and will do a hard stop
when time expires
  * Stack traces for the main thread are not much relevant
  * dispose window to exit gracefully on the success path

 * Removed unused code (button click action)

 * Added jtreg tags & copyright

Webrev.02 with test integrated:

 * http://cr.openjdk.java.net/~mbalao/webrevs/8204142/8204142.webrev.02
 * http://cr.openjdk.java.net/~mbalao/webrevs/8204142/8204142.webrev.02.zip

Kind regards,
Martin.-

On Mon, Oct 15, 2018 at 3:38 PM, Laurent Bourgès <bourges.laurent at gmail.com>
wrote:

> 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/20181016/ee40502e/attachment-0001.html>


More information about the awt-dev mailing list