1 /* 2 * Copyright (c) 2008, 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 6681889 27 @summary Showing a deserialized frame should not throw NPE 28 @author anthony.petrov@...: area=awt.toplevel 29 @run main PropertyChangeListenerLockSerialization 30 */ 31 32 33 /** 34 * PropertyChangeListenerLockSerialization.java 35 * 36 * summary: Showing a deserialized frame should not throw NPE 37 */ 38 39 import java.awt.*; 40 import java.awt.event.*; 41 import java.io.*; 42 import java.net.*; 43 44 public class PropertyChangeListenerLockSerialization 45 { 46 47 private static void init() 48 { 49 //*** Create instructions for the user here *** 50 51 String[] instructions = 52 { 53 "This is an AUTOMATIC test, simply wait until it is done.", 54 "The result (passed or failed) will be shown in the", 55 "message window below." 56 }; 57 Sysout.createDialog( ); 58 Sysout.printInstructions( instructions ); 59 60 File file = 61 new File(System.getProperty("test.classes", "."), "frame.ser"); 62 63 Frame f = new Frame("Frame"); 64 f.setBounds(250, 50, 300, 300); 65 try { 66 OutputStream o = new FileOutputStream(file); 67 ObjectOutputStream oo = new ObjectOutputStream(o); 68 69 oo.writeObject(f); 70 oo.close(); 71 } catch (IOException ex) { 72 ex.printStackTrace(); 73 fail("Unable to serialize the frame: " + ex); 74 } 75 76 // Cleanup the frame 77 f.dispose(); 78 f = null; 79 80 try { 81 ObjectInputStream i = new ObjectInputStream(new FileInputStream(file)); 82 83 f = (Frame)i.readObject(); 84 f.show(); 85 } catch (NullPointerException ex) { 86 ex.printStackTrace(); 87 fail("The NullPointerException has been thrown: " + ex); 88 } catch (Exception ex) { 89 ex.printStackTrace(); 90 fail("Error while deserializing the frame: " + ex); 91 } 92 93 // Cleanup the frame 94 f.dispose(); 95 f = null; 96 97 pass(); 98 99 }//End init() 100 101 102 103 /***************************************************** 104 * Standard Test Machinery Section 105 * DO NOT modify anything in this section -- it's a 106 * standard chunk of code which has all of the 107 * synchronisation necessary for the test harness. 108 * By keeping it the same in all tests, it is easier 109 * to read and understand someone else's test, as 110 * well as insuring that all tests behave correctly 111 * with the test harness. 112 * There is a section following this for test- 113 * classes 114 ******************************************************/ 115 private static boolean theTestPassed = false; 116 private static boolean testGeneratedInterrupt = false; 117 private static String failureMessage = ""; 118 119 private static Thread mainThread = null; 120 121 private static int sleepTime = 300000; 122 123 // Not sure about what happens if multiple of this test are 124 // instantiated in the same VM. Being static (and using 125 // static vars), it aint gonna work. Not worrying about 126 // it for now. 127 public static void main( String args[] ) throws InterruptedException 128 { 129 mainThread = Thread.currentThread(); 130 try 131 { 132 init(); 133 } 134 catch( TestPassedException e ) 135 { 136 //The test passed, so just return from main and harness will 137 // interepret this return as a pass 138 return; 139 } 140 //At this point, neither test pass nor test fail has been 141 // called -- either would have thrown an exception and ended the 142 // test, so we know we have multiple threads. 143 144 //Test involves other threads, so sleep and wait for them to 145 // called pass() or fail() 146 try 147 { 148 Thread.sleep( sleepTime ); 149 //Timed out, so fail the test 150 throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); 151 } 152 catch (InterruptedException e) 153 { 154 //The test harness may have interrupted the test. If so, rethrow the exception 155 // so that the harness gets it and deals with it. 156 if( ! testGeneratedInterrupt ) throw e; 157 158 //reset flag in case hit this code more than once for some reason (just safety) 159 testGeneratedInterrupt = false; 160 161 if ( theTestPassed == false ) 162 { 163 throw new RuntimeException( failureMessage ); 164 } 165 } 166 167 }//main 168 169 public static synchronized void setTimeoutTo( int seconds ) 170 { 171 sleepTime = seconds * 1000; 172 } 173 174 public static synchronized void pass() 175 { 176 Sysout.println( "The test passed." ); 177 Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); 178 //first check if this is executing in main thread 179 if ( mainThread == Thread.currentThread() ) 180 { 181 //Still in the main thread, so set the flag just for kicks, 182 // and throw a test passed exception which will be caught 183 // and end the test. 184 theTestPassed = true; 185 throw new TestPassedException(); 186 } 187 theTestPassed = true; 188 testGeneratedInterrupt = true; 189 mainThread.interrupt(); 190 }//pass() 191 192 public static synchronized void fail() 193 { 194 //test writer didn't specify why test failed, so give generic 195 fail( "it just plain failed! :-)" ); 196 } 197 198 public static synchronized void fail( String whyFailed ) 199 { 200 Sysout.println( "The test failed: " + whyFailed ); 201 Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); 202 //check if this called from main thread 203 if ( mainThread == Thread.currentThread() ) 204 { 205 //If main thread, fail now 'cause not sleeping 206 throw new RuntimeException( whyFailed ); 207 } 208 theTestPassed = false; 209 testGeneratedInterrupt = true; 210 failureMessage = whyFailed; 211 mainThread.interrupt(); 212 }//fail() 213 214 }// class PropertyChangeListenerLockSerialization 215 216 //This exception is used to exit from any level of call nesting 217 // when it's determined that the test has passed, and immediately 218 // end the test. 219 class TestPassedException extends RuntimeException 220 { 221 } 222 223 //*********** End Standard Test Machinery Section ********** 224 225 226 //************ Begin classes defined for the test **************** 227 228 // if want to make listeners, here is the recommended place for them, then instantiate 229 // them in init() 230 231 /* Example of a class which may be written as part of a test 232 class NewClass implements anInterface 233 { 234 static int newVar = 0; 235 236 public void eventDispatched(AWTEvent e) 237 { 238 //Counting events to see if we get enough 239 eventCount++; 240 241 if( eventCount == 20 ) 242 { 243 //got enough events, so pass 244 245 PropertyChangeListenerLockSerialization.pass(); 246 } 247 else if( tries == 20 ) 248 { 249 //tried too many times without getting enough events so fail 250 251 PropertyChangeListenerLockSerialization.fail(); 252 } 253 254 }// eventDispatched() 255 256 }// NewClass class 257 258 */ 259 260 261 //************** End classes defined for the test ******************* 262 263 264 265 266 /**************************************************** 267 Standard Test Machinery 268 DO NOT modify anything below -- it's a standard 269 chunk of code whose purpose is to make user 270 interaction uniform, and thereby make it simpler 271 to read and understand someone else's test. 272 ****************************************************/ 273 274 /** 275 This is part of the standard test machinery. 276 It creates a dialog (with the instructions), and is the interface 277 for sending text messages to the user. 278 To print the instructions, send an array of strings to Sysout.createDialog 279 WithInstructions method. Put one line of instructions per array entry. 280 To display a message for the tester to see, simply call Sysout.println 281 with the string to be displayed. 282 This mimics System.out.println but works within the test harness as well 283 as standalone. 284 */ 285 286 class Sysout 287 { 288 private static TestDialog dialog; 289 290 public static void createDialogWithInstructions( String[] instructions ) 291 { 292 dialog = new TestDialog( new Frame(), "Instructions" ); 293 dialog.printInstructions( instructions ); 294 dialog.setVisible(true); 295 println( "Any messages for the tester will display here." ); 296 } 297 298 public static void createDialog( ) 299 { 300 dialog = new TestDialog( new Frame(), "Instructions" ); 301 String[] defInstr = { "Instructions will appear here. ", "" } ; 302 dialog.printInstructions( defInstr ); 303 dialog.setVisible(true); 304 println( "Any messages for the tester will display here." ); 305 } 306 307 308 public static void printInstructions( String[] instructions ) 309 { 310 dialog.printInstructions( instructions ); 311 } 312 313 314 public static void println( String messageIn ) 315 { 316 dialog.displayMessage( messageIn ); 317 System.out.println(messageIn); 318 } 319 320 }// Sysout class 321 322 /** 323 This is part of the standard test machinery. It provides a place for the 324 test instructions to be displayed, and a place for interactive messages 325 to the user to be displayed. 326 To have the test instructions displayed, see Sysout. 327 To have a message to the user be displayed, see Sysout. 328 Do not call anything in this dialog directly. 329 */ 330 class TestDialog extends Dialog 331 { 332 333 TextArea instructionsText; 334 TextArea messageText; 335 int maxStringLength = 80; 336 337 //DO NOT call this directly, go through Sysout 338 public TestDialog( Frame frame, String name ) 339 { 340 super( frame, name ); 341 int scrollBoth = TextArea.SCROLLBARS_BOTH; 342 instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); 343 add( "North", instructionsText ); 344 345 messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); 346 add("Center", messageText); 347 348 pack(); 349 350 setVisible(true); 351 }// TestDialog() 352 353 //DO NOT call this directly, go through Sysout 354 public void printInstructions( String[] instructions ) 355 { 356 //Clear out any current instructions 357 instructionsText.setText( "" ); 358 359 //Go down array of instruction strings 360 361 String printStr, remainingStr; 362 for( int i=0; i < instructions.length; i++ ) 363 { 364 //chop up each into pieces maxSringLength long 365 remainingStr = instructions[ i ]; 366 while( remainingStr.length() > 0 ) 367 { 368 //if longer than max then chop off first max chars to print 369 if( remainingStr.length() >= maxStringLength ) 370 { 371 //Try to chop on a word boundary 372 int posOfSpace = remainingStr. 373 lastIndexOf( ' ', maxStringLength - 1 ); 374 375 if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; 376 377 printStr = remainingStr.substring( 0, posOfSpace + 1 ); 378 remainingStr = remainingStr.substring( posOfSpace + 1 ); 379 } 380 //else just print 381 else 382 { 383 printStr = remainingStr; 384 remainingStr = ""; 385 } 386 387 instructionsText.append( printStr + "\n" ); 388 389 }// while 390 391 }// for 392 393 }//printInstructions() 394 395 //DO NOT call this directly, go through Sysout 396 public void displayMessage( String messageIn ) 397 { 398 messageText.append( messageIn + "\n" ); 399 System.out.println(messageIn); 400 } 401 402 }// TestDialog class