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