1 /*
   2  * Copyright (c) 1998, 2010, 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         ThreadGroup mainThreadGroup = Thread.currentThread().getThreadGroup();
  53 
  54         long at;
  55         //wait for a TIMEOUT giving a chance to a new Thread above to accomplish its stuff.
  56         synchronized (LoopRobustness.LOCK) {
  57             new Thread(new TestThreadGroup(mainThreadGroup, "TestGroup"), new Impl()).start();
  58             at = System.currentTimeMillis();
  59             try {
  60                 while (!notifyOccured && (System.currentTimeMillis() - at < TIMEOUT)) {
  61                     LoopRobustness.LOCK.wait(1000);
  62                 }
  63             } catch (InterruptedException e) {
  64                 throw new RuntimeException("Test interrupted.", e);
  65             }
  66         }
  67 
  68         if (!notifyOccured) {
  69             //notify doesn't occur after a reasonable time.
  70             throw new RuntimeException("Test FAILED: second thread hasn't notified MainThread");
  71         }
  72 
  73         //now wait for two clicks
  74         at = System.currentTimeMillis();
  75         while(System.currentTimeMillis() - at < TIMEOUT && clicks < 2) {
  76             try {
  77                 Thread.sleep(100);
  78             } catch(InterruptedException e) {
  79                 throw new RuntimeException("Test interrupted.", e);
  80             }
  81         }
  82         if (clicks != 2) {
  83             throw new RuntimeException("Test FAILED: robot should press button twice");
  84         }
  85         if (otherExceptionsCaught) {
  86             throw new RuntimeException("Test FAILED: unexpected exceptions caught");
  87         }
  88     }
  89 }
  90 
  91 class Impl implements Runnable{
  92     static Robot robot;
  93     public void run() {
  94         SunToolkit.createNewAppContext();
  95 
  96         Button b = new Button("Press me to test the AWT-Event Queue thread");
  97         Frame lr = new Frame("ROBUST FRAME");
  98         lr.setBounds(100, 100, 300, 100);
  99         b.addActionListener(new ActionListener() {
 100                 public void actionPerformed(ActionEvent e) {
 101                     LoopRobustness.clicks++;
 102                     //throwing an exception in Static Initializer
 103                     System.out.println(HostileCrasher.aStaticMethod());
 104                 }
 105             });
 106         lr.add(b);
 107         lr.setVisible(true);
 108 
 109         try {
 110             robot = new Robot();
 111         } catch (AWTException e) {
 112             throw new RuntimeException("Test interrupted.", e);
 113         }
 114         Util.waitForIdle(robot);
 115 
 116         synchronized (LoopRobustness.LOCK){
 117             LoopRobustness.LOCK.notify();
 118             LoopRobustness.notifyOccured = true;
 119         }
 120 
 121         int i = 0;
 122         while (i < 2) {
 123             robot.mouseMove(b.getLocationOnScreen().x + b.getWidth()/2,
 124                             b.getLocationOnScreen().y + b.getHeight()/2);
 125             Util.waitForIdle(robot);
 126             robot.mousePress(InputEvent.BUTTON1_MASK);
 127             Util.waitForIdle(robot);
 128             robot.mouseRelease(InputEvent.BUTTON1_MASK);
 129             Util.waitForIdle(robot);
 130             i++;
 131         }
 132     }
 133 }
 134 
 135 class TestThreadGroup extends ThreadGroup {
 136     TestThreadGroup(ThreadGroup threadGroup, String name) {
 137         super(threadGroup, name);
 138     }
 139 
 140     public void uncaughtException(Thread thread, Throwable e) {
 141         System.out.println("Exception caught: " + e);
 142         e.printStackTrace(System.out);
 143         System.out.flush();
 144         if ((e instanceof ExceptionInInitializerError) ||
 145             (e instanceof NoClassDefFoundError))
 146         {
 147             // These two are expected
 148             return;
 149         }
 150         LoopRobustness.otherExceptionsCaught = true;
 151     }
 152 }
 153 
 154 class HostileCrasher {
 155     static {
 156         if (Math.random() >= 0.0) {
 157             throw new RuntimeException("Die, AWT-Event Queue thread!");
 158         }
 159     }
 160     public static String aStaticMethod() {
 161         return "hello, world";
 162     }
 163 }