1 /* 2 * Copyright (c) 2014, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 /* 27 * @test TestStableBoolean 28 * @summary tests on stable fields and arrays 29 * @library /testlibrary /test/lib 30 * @build TestStableBoolean StableConfiguration sun.hotspot.WhiteBox 31 * @run main ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission 32 * @run main ClassFileInstaller 33 * java/lang/invoke/StableConfiguration 34 * java/lang/invoke/TestStableBoolean 35 * java/lang/invoke/TestStableBoolean$BooleanStable 36 * java/lang/invoke/TestStableBoolean$StaticBooleanStable 37 * java/lang/invoke/TestStableBoolean$VolatileBooleanStable 38 * java/lang/invoke/TestStableBoolean$BooleanArrayDim1 39 * java/lang/invoke/TestStableBoolean$BooleanArrayDim2 40 * java/lang/invoke/TestStableBoolean$BooleanArrayDim3 41 * java/lang/invoke/TestStableBoolean$BooleanArrayDim4 42 * java/lang/invoke/TestStableBoolean$ObjectArrayLowerDim0 43 * java/lang/invoke/TestStableBoolean$ObjectArrayLowerDim1 44 * java/lang/invoke/TestStableBoolean$NestedStableField 45 * java/lang/invoke/TestStableBoolean$NestedStableField$A 46 * java/lang/invoke/TestStableBoolean$NestedStableField1 47 * java/lang/invoke/TestStableBoolean$NestedStableField1$A 48 * java/lang/invoke/TestStableBoolean$NestedStableField2 49 * java/lang/invoke/TestStableBoolean$NestedStableField2$A 50 * java/lang/invoke/TestStableBoolean$NestedStableField3 51 * java/lang/invoke/TestStableBoolean$NestedStableField3$A 52 * java/lang/invoke/TestStableBoolean$DefaultValue 53 * java/lang/invoke/TestStableBoolean$DefaultStaticValue 54 * java/lang/invoke/TestStableBoolean$ObjectArrayLowerDim2 55 * 56 * @run main/othervm -Xbootclasspath/a:. 57 * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp 58 * -XX:-TieredCompilation 59 * -XX:+FoldStableValues 60 * -XX:CompileOnly=::get,::get1,::get2,::get3,::get4 61 * java.lang.invoke.TestStableBoolean 62 * @run main/othervm -Xbootclasspath/a:. 63 * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp 64 * -XX:-TieredCompilation 65 * -XX:-FoldStableValues 66 * -XX:CompileOnly=::get,::get1,::get2,::get3,::get4 67 * java.lang.invoke.TestStableBoolean 68 * 69 * @run main/othervm -Xbootclasspath/a:. 70 * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp 71 * -XX:+TieredCompilation -XX:TieredStopAtLevel=1 72 * -XX:+FoldStableValues 73 * -XX:CompileOnly=::get,::get1,::get2,::get3,::get4 74 * java.lang.invoke.TestStableBoolean 75 * @run main/othervm -Xbootclasspath/a:. 76 * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp 77 * -XX:+TieredCompilation -XX:TieredStopAtLevel=1 78 * -XX:-FoldStableValues 79 * -XX:CompileOnly=::get,::get1,::get2,::get3,::get4 80 * java.lang.invoke.TestStableBoolean 81 * 82 */ 83 package java.lang.invoke; 84 85 import jdk.internal.vm.annotation.Stable; 86 87 import java.lang.reflect.InvocationTargetException; 88 89 public class TestStableBoolean { 90 static final boolean isStableEnabled = StableConfiguration.isStableEnabled; 91 static final boolean isServerWithStable = StableConfiguration.isServerWithStable; 92 93 public static void main(String[] args) throws Exception { 94 run(DefaultValue.class); 95 run(BooleanStable.class); 96 run(DefaultStaticValue.class); 97 run(StaticBooleanStable.class); 98 run(VolatileBooleanStable.class); 99 100 // @Stable arrays: Dim 1-4 101 run(BooleanArrayDim1.class); 102 run(BooleanArrayDim2.class); 103 run(BooleanArrayDim3.class); 104 run(BooleanArrayDim4.class); 105 106 // @Stable Object field: dynamic arrays 107 run(ObjectArrayLowerDim0.class); 108 run(ObjectArrayLowerDim1.class); 109 run(ObjectArrayLowerDim2.class); 110 111 // Nested @Stable fields 112 run(NestedStableField.class); 113 run(NestedStableField1.class); 114 run(NestedStableField2.class); 115 run(NestedStableField3.class); 116 117 if (failed) { 118 throw new Error("TEST FAILED"); 119 } 120 } 121 122 /* ==================================================== */ 123 124 static class DefaultValue { 125 public @Stable boolean v; 126 127 public static final DefaultValue c = new DefaultValue(); 128 public static boolean get() { return c.v; } 129 public static void test() throws Exception { 130 boolean val1 = get(); 131 c.v = true; boolean val2 = get(); 132 assertEquals(val1, false); 133 assertEquals(val2, true); 134 } 135 } 136 137 /* ==================================================== */ 138 139 static class BooleanStable { 140 public @Stable boolean v; 141 142 public static final BooleanStable c = new BooleanStable(); 143 public static boolean get() { return c.v; } 144 public static void test() throws Exception { 145 c.v = true; boolean val1 = get(); 146 c.v = false; boolean val2 = get(); 147 assertEquals(val1, true); 148 assertEquals(val2, (isStableEnabled ? true : false)); 149 } 150 } 151 152 /* ==================================================== */ 153 154 static class DefaultStaticValue { 155 public static @Stable boolean v; 156 157 public static final DefaultStaticValue c = new DefaultStaticValue(); 158 public static boolean get() { return c.v; } 159 public static void test() throws Exception { 160 boolean val1 = get(); 161 c.v = true; boolean val2 = get(); 162 assertEquals(val1, false); 163 assertEquals(val2, true); 164 } 165 } 166 167 /* ==================================================== */ 168 169 static class StaticBooleanStable { 170 public static @Stable boolean v; 171 172 public static final StaticBooleanStable c = new StaticBooleanStable(); 173 public static boolean get() { return c.v; } 174 public static void test() throws Exception { 175 c.v = true; boolean val1 = get(); 176 c.v = false; boolean val2 = get(); 177 assertEquals(val1, true); 178 assertEquals(val2, (isStableEnabled ? true : false)); 179 } 180 } 181 182 /* ==================================================== */ 183 184 static class VolatileBooleanStable { 185 public @Stable volatile boolean v; 186 187 public static final VolatileBooleanStable c = new VolatileBooleanStable(); 188 public static boolean get() { return c.v; } 189 public static void test() throws Exception { 190 c.v = true; boolean val1 = get(); 191 c.v = false; boolean val2 = get(); 192 assertEquals(val1, true); 193 assertEquals(val2, (isStableEnabled ? true : false)); 194 } 195 } 196 197 /* ==================================================== */ 198 // @Stable array == field && all components are stable 199 200 static class BooleanArrayDim1 { 201 public @Stable boolean[] v; 202 203 public static final BooleanArrayDim1 c = new BooleanArrayDim1(); 204 public static boolean get() { return c.v[0]; } 205 public static boolean get1() { return c.v[10]; } 206 public static boolean[] get2() { return c.v; } 207 public static void test() throws Exception { 208 { 209 c.v = new boolean[1]; c.v[0] = true; boolean val1 = get(); 210 c.v[0] = false; boolean val2 = get(); 211 assertEquals(val1, true); 212 assertEquals(val2, (isServerWithStable ? true : false)); 213 } 214 215 { 216 c.v = new boolean[20]; c.v[10] = true; boolean val1 = get1(); 217 c.v[10] = false; boolean val2 = get1(); 218 assertEquals(val1, true); 219 assertEquals(val2, (isServerWithStable ? true : false)); 220 } 221 222 { 223 c.v = new boolean[1]; boolean[] val1 = get2(); 224 c.v = new boolean[1]; boolean[] val2 = get2(); 225 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 226 } 227 } 228 } 229 230 /* ==================================================== */ 231 232 static class BooleanArrayDim2 { 233 public @Stable boolean[][] v; 234 235 public static final BooleanArrayDim2 c = new BooleanArrayDim2(); 236 public static boolean get() { return c.v[0][0]; } 237 public static boolean[] get1() { return c.v[0]; } 238 public static boolean[][] get2() { return c.v; } 239 public static void test() throws Exception { 240 { 241 c.v = new boolean[1][1]; c.v[0][0] = true; boolean val1 = get(); 242 c.v[0][0] = false; boolean val2 = get(); 243 assertEquals(val1, true); 244 assertEquals(val2, (isServerWithStable ? true : false)); 245 246 c.v = new boolean[1][1]; c.v[0][0] = false; boolean val3 = get(); 247 assertEquals(val3, (isServerWithStable ? true : false)); 248 249 c.v[0] = new boolean[1]; c.v[0][0] = false; boolean val4 = get(); 250 assertEquals(val4, (isServerWithStable ? true : false)); 251 } 252 253 { 254 c.v = new boolean[1][1]; boolean[] val1 = get1(); 255 c.v[0] = new boolean[1]; boolean[] val2 = get1(); 256 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2))); 257 } 258 259 { 260 c.v = new boolean[1][1]; boolean[][] val1 = get2(); 261 c.v = new boolean[1][1]; boolean[][] val2 = get2(); 262 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 263 } 264 } 265 } 266 267 /* ==================================================== */ 268 269 static class BooleanArrayDim3 { 270 public @Stable boolean[][][] v; 271 272 public static final BooleanArrayDim3 c = new BooleanArrayDim3(); 273 public static boolean get() { return c.v[0][0][0]; } 274 public static boolean[] get1() { return c.v[0][0]; } 275 public static boolean[][] get2() { return c.v[0]; } 276 public static boolean[][][] get3() { return c.v; } 277 public static void test() throws Exception { 278 { 279 c.v = new boolean[1][1][1]; c.v[0][0][0] = true; boolean val1 = get(); 280 c.v[0][0][0] = false; boolean val2 = get(); 281 assertEquals(val1, true); 282 assertEquals(val2, (isServerWithStable ? true : false)); 283 284 c.v = new boolean[1][1][1]; c.v[0][0][0] = false; boolean val3 = get(); 285 assertEquals(val3, (isServerWithStable ? true : false)); 286 287 c.v[0] = new boolean[1][1]; c.v[0][0][0] = false; boolean val4 = get(); 288 assertEquals(val4, (isServerWithStable ? true : false)); 289 290 c.v[0][0] = new boolean[1]; c.v[0][0][0] = false; boolean val5 = get(); 291 assertEquals(val5, (isServerWithStable ? true : false)); 292 } 293 294 { 295 c.v = new boolean[1][1][1]; boolean[] val1 = get1(); 296 c.v[0][0] = new boolean[1]; boolean[] val2 = get1(); 297 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2))); 298 } 299 300 { 301 c.v = new boolean[1][1][1]; boolean[][] val1 = get2(); 302 c.v[0] = new boolean[1][1]; boolean[][] val2 = get2(); 303 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2))); 304 } 305 306 { 307 c.v = new boolean[1][1][1]; boolean[][][] val1 = get3(); 308 c.v = new boolean[1][1][1]; boolean[][][] val2 = get3(); 309 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 310 } 311 } 312 } 313 314 /* ==================================================== */ 315 316 static class BooleanArrayDim4 { 317 public @Stable boolean[][][][] v; 318 319 public static final BooleanArrayDim4 c = new BooleanArrayDim4(); 320 public static boolean get() { return c.v[0][0][0][0]; } 321 public static boolean[] get1() { return c.v[0][0][0]; } 322 public static boolean[][] get2() { return c.v[0][0]; } 323 public static boolean[][][] get3() { return c.v[0]; } 324 public static boolean[][][][] get4() { return c.v; } 325 public static void test() throws Exception { 326 { 327 c.v = new boolean[1][1][1][1]; c.v[0][0][0][0] = true; boolean val1 = get(); 328 c.v[0][0][0][0] = false; boolean val2 = get(); 329 assertEquals(val1, true); 330 assertEquals(val2, (isServerWithStable ? true : false)); 331 332 c.v = new boolean[1][1][1][1]; c.v[0][0][0][0] = false; boolean val3 = get(); 333 assertEquals(val3, (isServerWithStable ? true : false)); 334 335 c.v[0] = new boolean[1][1][1]; c.v[0][0][0][0] = false; boolean val4 = get(); 336 assertEquals(val4, (isServerWithStable ? true : false)); 337 338 c.v[0][0] = new boolean[1][1]; c.v[0][0][0][0] = false; boolean val5 = get(); 339 assertEquals(val5, (isServerWithStable ? true : false)); 340 341 c.v[0][0][0] = new boolean[1]; c.v[0][0][0][0] = false; boolean val6 = get(); 342 assertEquals(val6, (isServerWithStable ? true : false)); 343 } 344 345 { 346 c.v = new boolean[1][1][1][1]; boolean[] val1 = get1(); 347 c.v[0][0][0] = new boolean[1]; boolean[] val2 = get1(); 348 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2))); 349 } 350 351 { 352 c.v = new boolean[1][1][1][1]; boolean[][] val1 = get2(); 353 c.v[0][0] = new boolean[1][1]; boolean[][] val2 = get2(); 354 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2))); 355 } 356 357 { 358 c.v = new boolean[1][1][1][1]; boolean[][][] val1 = get3(); 359 c.v[0] = new boolean[1][1][1]; boolean[][][] val2 = get3(); 360 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2))); 361 } 362 363 { 364 c.v = new boolean[1][1][1][1]; boolean[][][][] val1 = get4(); 365 c.v = new boolean[1][1][1][1]; boolean[][][][] val2 = get4(); 366 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 367 } 368 369 } 370 } 371 372 /* ==================================================== */ 373 // Dynamic Dim is higher than static 374 375 static class ObjectArrayLowerDim0 { 376 public @Stable Object v; 377 378 public static final ObjectArrayLowerDim0 c = new ObjectArrayLowerDim0(); 379 public static boolean get() { return ((boolean[])c.v)[0]; } 380 public static boolean[] get1() { return (boolean[])c.v; } 381 public static boolean[] get2() { return (boolean[])c.v; } 382 383 public static void test() throws Exception { 384 { 385 c.v = new boolean[1]; ((boolean[])c.v)[0] = true; boolean val1 = get(); 386 ((boolean[])c.v)[0] = false; boolean val2 = get(); 387 388 assertEquals(val1, true); 389 assertEquals(val2, false); 390 } 391 392 { 393 c.v = new boolean[1]; boolean[] val1 = get1(); 394 c.v = new boolean[1]; boolean[] val2 = get1(); 395 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 396 } 397 } 398 } 399 400 /* ==================================================== */ 401 402 static class ObjectArrayLowerDim1 { 403 public @Stable Object[] v; 404 405 public static final ObjectArrayLowerDim1 c = new ObjectArrayLowerDim1(); 406 public static boolean get() { return ((boolean[][])c.v)[0][0]; } 407 public static boolean[] get1() { return (boolean[])(c.v[0]); } 408 public static Object[] get2() { return c.v; } 409 410 public static void test() throws Exception { 411 { 412 c.v = new boolean[1][1]; ((boolean[][])c.v)[0][0] = true; boolean val1 = get(); 413 ((boolean[][])c.v)[0][0] = false; boolean val2 = get(); 414 415 assertEquals(val1, true); 416 assertEquals(val2, false); 417 } 418 419 { 420 c.v = new boolean[1][1]; c.v[0] = new boolean[0]; boolean[] val1 = get1(); 421 c.v[0] = new boolean[0]; boolean[] val2 = get1(); 422 423 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2))); 424 } 425 426 { 427 c.v = new boolean[0][0]; Object[] val1 = get2(); 428 c.v = new boolean[0][0]; Object[] val2 = get2(); 429 430 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 431 } 432 } 433 } 434 435 /* ==================================================== */ 436 437 static class ObjectArrayLowerDim2 { 438 public @Stable Object[][] v; 439 440 public static final ObjectArrayLowerDim2 c = new ObjectArrayLowerDim2(); 441 public static boolean get() { return ((boolean[][][])c.v)[0][0][0]; } 442 public static boolean[] get1() { return (boolean[])(c.v[0][0]); } 443 public static boolean[][] get2() { return (boolean[][])(c.v[0]); } 444 public static Object[][] get3() { return c.v; } 445 446 public static void test() throws Exception { 447 { 448 c.v = new boolean[1][1][1]; ((boolean[][][])c.v)[0][0][0] = true; boolean val1 = get(); 449 ((boolean[][][])c.v)[0][0][0] = false; boolean val2 = get(); 450 451 assertEquals(val1, true); 452 assertEquals(val2, false); 453 } 454 455 { 456 c.v = new boolean[1][1][1]; c.v[0][0] = new boolean[0]; boolean[] val1 = get1(); 457 c.v[0][0] = new boolean[0]; boolean[] val2 = get1(); 458 459 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2))); 460 } 461 462 { 463 c.v = new boolean[1][1][1]; c.v[0] = new boolean[0][0]; boolean[][] val1 = get2(); 464 c.v[0] = new boolean[0][0]; boolean[][] val2 = get2(); 465 466 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2))); 467 } 468 469 { 470 c.v = new boolean[0][0][0]; Object[][] val1 = get3(); 471 c.v = new boolean[0][0][0]; Object[][] val2 = get3(); 472 473 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 474 } 475 } 476 } 477 478 /* ==================================================== */ 479 480 static class NestedStableField { 481 static class A { 482 public @Stable boolean a; 483 484 } 485 public @Stable A v; 486 487 public static final NestedStableField c = new NestedStableField(); 488 public static A get() { return c.v; } 489 public static boolean get1() { return get().a; } 490 491 public static void test() throws Exception { 492 { 493 c.v = new A(); c.v.a = true; A val1 = get(); 494 c.v.a = false; A val2 = get(); 495 496 assertEquals(val1.a, false); 497 assertEquals(val2.a, false); 498 } 499 500 { 501 c.v = new A(); c.v.a = true; boolean val1 = get1(); 502 c.v.a = false; boolean val2 = get1(); 503 c.v = new A(); c.v.a = false; boolean val3 = get1(); 504 505 assertEquals(val1, true); 506 assertEquals(val2, (isStableEnabled ? true : false)); 507 assertEquals(val3, (isStableEnabled ? true : false)); 508 } 509 } 510 } 511 512 /* ==================================================== */ 513 514 static class NestedStableField1 { 515 static class A { 516 public @Stable boolean a; 517 public @Stable A next; 518 } 519 public @Stable A v; 520 521 public static final NestedStableField1 c = new NestedStableField1(); 522 public static A get() { return c.v.next.next.next.next.next.next.next; } 523 public static boolean get1() { return get().a; } 524 525 public static void test() throws Exception { 526 { 527 c.v = new A(); c.v.next = new A(); c.v.next.next = c.v; 528 c.v.a = true; c.v.next.a = true; A val1 = get(); 529 c.v.a = false; c.v.next.a = false; A val2 = get(); 530 531 assertEquals(val1.a, false); 532 assertEquals(val2.a, false); 533 } 534 535 { 536 c.v = new A(); c.v.next = c.v; 537 c.v.a = true; boolean val1 = get1(); 538 c.v.a = false; boolean val2 = get1(); 539 c.v = new A(); c.v.next = c.v; 540 c.v.a = false; boolean val3 = get1(); 541 542 assertEquals(val1, true); 543 assertEquals(val2, (isStableEnabled ? true : false)); 544 assertEquals(val3, (isStableEnabled ? true : false)); 545 } 546 } 547 } 548 /* ==================================================== */ 549 550 static class NestedStableField2 { 551 static class A { 552 public @Stable boolean a; 553 public @Stable A left; 554 public A right; 555 } 556 557 public @Stable A v; 558 559 public static final NestedStableField2 c = new NestedStableField2(); 560 public static boolean get() { return c.v.left.left.left.a; } 561 public static boolean get1() { return c.v.left.left.right.left.a; } 562 563 public static void test() throws Exception { 564 { 565 c.v = new A(); c.v.left = c.v.right = c.v; 566 c.v.a = true; boolean val1 = get(); boolean val2 = get1(); 567 c.v.a = false; boolean val3 = get(); boolean val4 = get1(); 568 569 assertEquals(val1, true); 570 assertEquals(val3, (isStableEnabled ? true : false)); 571 572 assertEquals(val2, true); 573 assertEquals(val4, false); 574 } 575 } 576 } 577 578 /* ==================================================== */ 579 580 static class NestedStableField3 { 581 static class A { 582 public @Stable boolean a; 583 public @Stable A[] left; 584 public A[] right; 585 } 586 587 public @Stable A[] v; 588 589 public static final NestedStableField3 c = new NestedStableField3(); 590 public static boolean get() { return c.v[0].left[1].left[0].left[1].a; } 591 public static boolean get1() { return c.v[1].left[0].left[1].right[0].left[1].a; } 592 593 public static void test() throws Exception { 594 { 595 A elem = new A(); 596 c.v = new A[] { elem, elem }; c.v[0].left = c.v[0].right = c.v; 597 elem.a = true; boolean val1 = get(); boolean val2 = get1(); 598 elem.a = false; boolean val3 = get(); boolean val4 = get1(); 599 600 assertEquals(val1, true); 601 assertEquals(val3, (isServerWithStable ? true : false)); 602 603 assertEquals(val2, true); 604 assertEquals(val4, false); 605 } 606 } 607 } 608 609 /* ==================================================== */ 610 // Auxiliary methods 611 static void assertEquals(boolean i, boolean j) { if (i != j) throw new AssertionError(i + " != " + j); } 612 static void assertTrue(boolean b) { if (!b) throw new AssertionError(); } 613 614 static boolean failed = false; 615 616 public static void run(Class<?> test) { 617 Throwable ex = null; 618 System.out.print(test.getName()+": "); 619 try { 620 test.getMethod("test").invoke(null); 621 } catch (InvocationTargetException e) { 622 ex = e.getCause(); 623 } catch (Throwable e) { 624 ex = e; 625 } finally { 626 if (ex == null) { 627 System.out.println("PASSED"); 628 } else { 629 failed = true; 630 System.out.println("FAILED"); 631 ex.printStackTrace(System.out); 632 } 633 } 634 } 635 }