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