1 /*
   2  * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /**
  25  *
  26  * @bug 4023283
  27  * @summary Checks that an Error which propogate up to the EventDispatch
  28  * loop does not crash AWT.
  29  * @author Andrei Dmitriev: area=awt.event
  30  * @library ../../regtesthelpers
  31  * @build Util
  32  * @run main LoopRobustness
  33  */
  34 
  35 import java.awt.*;
  36 import java.awt.event.*;
  37 
  38 import sun.awt.SunToolkit;
  39 
  40 import test.java.awt.regtesthelpers.Util;
  41 
  42 public class LoopRobustness {
  43 
  44     final static long TIMEOUT = 5000;
  45     final static Object LOCK = new Object();
  46 
  47     public static int clicks = 0;
  48     public static volatile boolean notifyOccured = false;
  49     public static volatile boolean otherExceptionsCaught = false;
  50 
  51     public static void main(String [] args) throws Exception {
  52         SunToolkit.createNewAppContext();
  53 
  54         ThreadGroup mainThreadGroup = Thread.currentThread().getThreadGroup();
  55 
  56         long at;
  57         //wait for a TIMEOUT giving a chance to a new Thread above to accomplish its stuff.
  58         synchronized (LoopRobustness.LOCK) {
  59             new Thread(new TestThreadGroup(mainThreadGroup, "TestGroup"), new Impl()).start();
  60             at = System.currentTimeMillis();
  61             try {
  62                 while (!notifyOccured && (System.currentTimeMillis() - at < TIMEOUT)) {
  63                     LoopRobustness.LOCK.wait(1000);
  64                 }
  65             } catch (InterruptedException e) {
  66                 throw new RuntimeException("Test interrupted.", e);
  67             }
  68         }
  69 
  70         if (!notifyOccured) {
  71             //notify doesn't occur after a reasonable time.
  72             throw new RuntimeException("Test FAILED: second thread hasn't notified MainThread");
  73         }
  74 
  75         //now wait for two clicks
  76         at = System.currentTimeMillis();
  77         while(System.currentTimeMillis() - at < TIMEOUT && clicks < 2) {
  78             try {
  79                 Thread.sleep(100);
  80             } catch(InterruptedException e) {
  81                 throw new RuntimeException("Test interrupted.", e);
  82             }
  83         }
  84         if (clicks != 2) {
  85             throw new RuntimeException("Test FAILED: robot should press button twice");
  86         }
  87         if (otherExceptionsCaught) {
  88             throw new RuntimeException("Test FAILED: unexpected exceptions caught");
  89         }
  90     }
  91 }
  92 
  93 class Impl implements Runnable{
  94     static Robot robot;
  95     public void run() {
  96         SunToolkit.createNewAppContext();
  97 
  98         Button b = new Button("Press me to test the AWT-Event Queue thread");
  99         Frame lr = new Frame("ROBUST FRAME");
 100         lr.setBounds(100, 100, 300, 100);
 101         b.addActionListener(new ActionListener() {
 102                 public void actionPerformed(ActionEvent e) {
 103                     LoopRobustness.clicks++;
 104                     //throwing an exception in Static Initializer
 105                     System.out.println(HostileCrasher.aStaticMethod());
 106                 }
 107             });
 108         lr.add(b);
 109         lr.setVisible(true);
 110 
 111         try {
 112             robot = new Robot();
 113         } catch (AWTException e) {
 114             throw new RuntimeException("Test interrupted.", e);
 115         }
 116         Util.waitForIdle(robot);
 117 
 118         synchronized (LoopRobustness.LOCK){
 119             LoopRobustness.LOCK.notify();
 120             LoopRobustness.notifyOccured = true;
 121         }
 122 
 123         int i = 0;
 124         while (i < 2) {
 125             robot.mouseMove(b.getLocationOnScreen().x + b.getWidth()/2,
 126                             b.getLocationOnScreen().y + b.getHeight()/2);
 127             Util.waitForIdle(robot);
 128             robot.mousePress(InputEvent.BUTTON1_MASK);
 129             Util.waitForIdle(robot);
 130             robot.mouseRelease(InputEvent.BUTTON1_MASK);
 131             Util.waitForIdle(robot);
 132             i++;
 133         }
 134     }
 135 }
 136 
 137 class TestThreadGroup extends ThreadGroup {
 138     TestThreadGroup(ThreadGroup threadGroup, String name) {
 139         super(threadGroup, name);
 140     }
 141 
 142     public void uncaughtException(Thread thread, Throwable e) {
 143         System.out.println("Exception caught: " + e);
 144         e.printStackTrace(System.out);
 145         System.out.flush();
 146         if ((e instanceof ExceptionInInitializerError) ||
 147             (e instanceof NoClassDefFoundError))
 148         {
 149             // These two are expected
 150             return;
 151         }
 152         LoopRobustness.otherExceptionsCaught = true;
 153     }
 154 }
 155 
 156 class HostileCrasher {
 157     static {
 158         if (Math.random() >= 0.0) {
 159             throw new RuntimeException("Die, AWT-Event Queue thread!");
 160         }
 161     }
 162     public static String aStaticMethod() {
 163         return "hello, world";
 164     }
 165 }