1 /*
   2  * Copyright (c) 2009, 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 /* @test
  25    @bug 6799345
  26    @summary Tests that no exceptions are thrown from TimerQueue and
  27 SwingWorker on AppContext shutdown
  28    @author art
  29    @run main TestShutdown
  30 */
  31 
  32 import java.awt.*;
  33 import java.awt.event.*;
  34 
  35 import java.util.*;
  36 
  37 import javax.swing.*;
  38 
  39 import sun.awt.*;
  40 
  41 public class TestShutdown
  42 {
  43     private static AppContext targetAppContext;
  44 
  45     private static JFrame f;
  46     private static JTextField tf;
  47 
  48     private static volatile boolean exceptionsOccurred = false;
  49     private static volatile boolean appcontextInitDone = false;
  50 
  51     private static int timerValue = 0;
  52 
  53     public static void main(String[] args)
  54         throws Exception
  55     {
  56         ThreadGroup tg = new TestThreadGroup("TTG");
  57         Thread t = new Thread(tg, new TestRunnable(), "InitThread");
  58         t.start();
  59 
  60         while (!appcontextInitDone)
  61         {
  62             Thread.sleep(1000);
  63         }
  64 
  65         targetAppContext.dispose();
  66 
  67         if (exceptionsOccurred)
  68         {
  69             throw new RuntimeException("Test FAILED: some exceptions occurred");
  70         }
  71     }
  72 
  73     static void initGUI()
  74     {
  75         f = new JFrame("F");
  76         f.setBounds(100, 100, 200, 100);
  77         tf = new JTextField("Test");
  78         f.add(tf);
  79         f.setVisible(true);
  80     }
  81 
  82     static void startGUI()
  83     {
  84         // caret blink Timer
  85         tf.requestFocusInWindow();
  86 
  87         // misc Timer
  88         ActionListener al = new ActionListener()
  89         {
  90             @Override
  91             public void actionPerformed(ActionEvent ae)
  92             {
  93                 System.out.println("Timer tick: " + timerValue++);
  94             }
  95         };
  96         new javax.swing.Timer(30, al).start();
  97     }
  98 
  99     static class TestThreadGroup extends ThreadGroup
 100     {
 101         public TestThreadGroup(String name)
 102         {
 103             super(name);
 104         }
 105 
 106         @Override
 107         public synchronized void uncaughtException(Thread thread, Throwable t)
 108         {
 109             if (t instanceof ThreadDeath)
 110             {
 111                 // this one is expected, rethrow
 112                 throw (ThreadDeath)t;
 113             }
 114             System.err.println("Test FAILED: an exception is caught in the " +
 115                                "target thread group on thread " + thread.getName());
 116             t.printStackTrace(System.err);
 117             exceptionsOccurred = true;
 118         }
 119     }
 120 
 121     static class TestRunnable implements Runnable
 122     {
 123         @Override
 124         public void run()
 125         {
 126             SunToolkit stk = (SunToolkit)Toolkit.getDefaultToolkit();
 127             targetAppContext = stk.createNewAppContext();
 128 
 129             // create and show frame and text field
 130             SwingUtilities.invokeLater(new Runnable()
 131             {
 132                 @Override
 133                 public void run()
 134                 {
 135                     initGUI();
 136                 }
 137             });
 138             stk.realSync();
 139 
 140             // start some Timers
 141             SwingUtilities.invokeLater(new Runnable()
 142             {
 143                 @Override
 144                 public void run()
 145                 {
 146                     startGUI();
 147                 }
 148             });
 149 
 150             // start multiple SwingWorkers
 151             while (!Thread.interrupted())
 152             {
 153                 try
 154                 {
 155                     new TestSwingWorker().execute();
 156                     Thread.sleep(40);
 157                 }
 158                 catch (Exception e)
 159                 {
 160                     // exception here is expected, skip
 161                     break;
 162                 }
 163             }
 164         }
 165     }
 166 
 167     static class TestSwingWorker extends SwingWorker<String, Integer>
 168     {
 169         @Override
 170         public String doInBackground()
 171         {
 172             Random r = new Random();
 173             for (int i = 0; i < 10; i++)
 174             {
 175                 try
 176                 {
 177                     int delay = r.nextInt() % 50;
 178                     Thread.sleep(delay);
 179                     publish(delay);
 180                 }
 181                 catch (Exception z)
 182                 {
 183                     break;
 184                 }
 185             }
 186             if (!appcontextInitDone)
 187             {
 188                 appcontextInitDone = true;
 189             }
 190             return "Done";
 191         }
 192 
 193         @Override
 194         public void process(java.util.List<Integer> chunks)
 195         {
 196             for (Integer i : chunks)
 197             {
 198                 System.err.println("Processed: " + i);
 199             }
 200         }
 201     }
 202 }