1 /* 2 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. 3 * Copyright (c) 2019 SAP SE. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 */ 24 25 /** 26 * @test 27 * @summary Test extended NullPointerException message for class 28 * files generated without debugging information. The message lists 29 * detailed information about the entity that is null. 30 * @library /test/lib 31 * @compile NullPointerExceptionTest.java 32 * @run main NullPointerExceptionTest 33 */ 34 /** 35 * @test 36 * @summary Test extended NullPointerException message for 37 * classfiles generated with debug information. In this case the name 38 * of the variable containing the array is printed. 39 * @library /test/lib 40 * @compile -g NullPointerExceptionTest.java 41 * @run main/othervm -DhasDebugInfo NullPointerExceptionTest 42 */ 43 44 import java.io.ByteArrayInputStream; 45 import java.io.ByteArrayOutputStream; 46 import java.io.ObjectInputStream; 47 import java.io.ObjectOutputStream; 48 import java.util.ArrayList; 49 50 import jdk.test.lib.Asserts; 51 52 /** 53 * Tests NullPointerExceptions 54 */ 55 public class NullPointerExceptionTest { 56 // Some fields used in the test. 57 static Object nullStaticField; 58 NullPointerExceptionTest nullInstanceField; 59 static int[][][][] staticArray; 60 static long[][] staticLongArray = new long[1000][]; 61 DoubleArrayGen dag; 62 ArrayList<String> names = new ArrayList<>(); 63 ArrayList<String> curr; 64 static boolean hasDebugInfo = true; 65 66 static { 67 try { 68 hasDebugInfo = System.getProperty("hasDebugInfo") != null; 69 } catch (Throwable t) { 70 throw new RuntimeException(t); 71 } 72 73 staticArray = new int[1][][][]; 74 staticArray[0] = new int[1][][]; 75 staticArray[0][0] = new int[1][]; 76 } 77 78 public static void checkMessage(String expression, 79 String obtainedMsg, String expectedMsg) { 80 System.out.println(); 81 System.out.println(" source code: " + expression); 82 System.out.println(" thrown msg: " + obtainedMsg); 83 //System.out.println("expected msg: " + expectedMsg); 84 //Asserts.assertEquals(obtainedMsg, expectedMsg); 85 } 86 87 public static void main(String[] args) throws Exception { 88 NullPointerExceptionTest t = new NullPointerExceptionTest(); 89 t.testPointerChasing(); 90 t.testArrayChasing(); 91 t.testMethodChasing(); 92 t.testSameMessage(); 93 t.testCreationViaNew(); 94 t.testCreationViaReflection(); 95 t.testCreationViaSerialization(); 96 t.testLoadedFromLocalVariable1(); 97 t.testLoadedFromLocalVariable2(); 98 t.testLoadedFromLocalVariable3(); 99 t.testLoadedFromLocalVariable4(); 100 t.testLoadedFromLocalVariable5(); 101 t.testLoadedFromLocalVariable6(); 102 t.testLoadedFromLocalVariable7(); 103 t.testLoadedFromMethod1(); 104 t.testLoadedFromMethod2(); 105 t.testLoadedFromMethod3(); 106 t.testLoadedFromMethod4(); 107 t.testLoadedFromMethod5(); 108 t.testLoadedFromMethod6(); 109 t.testLoadedFromMethod7(); 110 t.testLoadedFromStaticField1(); 111 t.testLoadedFromStaticField2(); 112 t.testLoadedFromStaticField3(); 113 t.testLoadedFromStaticField4(0, 0); 114 t.testLoadedFromStaticField5(); 115 t.testLoadedFromStaticField5a(); 116 t.testLoadedFromStaticField5b(); 117 t.testLoadedFromStaticField6(); 118 t.testLoadedFromInstanceField1(); 119 t.testLoadedFromInstanceField2(); 120 t.testLoadedFromInstanceField3(); 121 t.testLoadedFromInstanceField4(); 122 t.testLoadedFromInstanceField5(); 123 t.testLoadedFromInstanceField6(); 124 t.testInNative(); 125 t.testMissingLocalVariableTable(); 126 t.testNullMessages(); 127 } 128 129 class A { 130 public B to_b; 131 public B getB() { return to_b; } 132 } 133 134 class B { 135 public C to_c; 136 public B to_b; 137 public C getC() { return to_c; } 138 public B getBfromB() { return to_b; } 139 } 140 141 class C { 142 public D to_d; 143 public D getD() { return to_d; } 144 } 145 146 class D { 147 public int num; 148 } 149 150 public void testPointerChasing() { 151 A a = null; 152 try { 153 a.to_b.to_c.to_d.num = 99; 154 Asserts.fail(); 155 } catch (NullPointerException e) { 156 checkMessage("a.to_b.to_c.to_d.num = 99 // a is null", e.getMessage(), 157 "while trying to read the field 'to_b' of a null object loaded from " + 158 (hasDebugInfo ? "local variable 'a'" : "a local variable at slot 1")); 159 } 160 a = new A(); 161 try { 162 a.to_b.to_c.to_d.num = 99; 163 Asserts.fail(); 164 } catch (NullPointerException e) { 165 checkMessage("a.to_b.to_c.to_d.num = 99 // a.to_b is null", e.getMessage(), 166 "while trying to read the field 'to_c' of a null object loaded from field 'NullPointerExceptionTest$A.to_b' of an object loaded from " + 167 (hasDebugInfo ? "local variable 'a'" : "a local variable at slot 1")); 168 } 169 a.to_b = new B(); 170 try { 171 a.to_b.to_c.to_d.num = 99; 172 Asserts.fail(); 173 } catch (NullPointerException e) { 174 checkMessage("a.to_b.to_c.to_d.num = 99 // a.to_b.to_c is null", e.getMessage(), 175 "while trying to read the field 'to_d' of a null object loaded from field 'NullPointerExceptionTest$B.to_c' of an object loaded from field 'NullPointerExceptionTest$A.to_b' of an object"); 176 } 177 a.to_b.to_c = new C(); 178 try { 179 a.to_b.to_c.to_d.num = 99; 180 Asserts.fail(); 181 } catch (NullPointerException e) { 182 checkMessage("a.to_b.to_c.to_d.num = 99 // a.to_b.to_c.to_d is null", e.getMessage(), 183 "while trying to write the field 'NullPointerExceptionTest$D.num' of a null object loaded from field 'NullPointerExceptionTest$C.to_d' of an object loaded from field 'NullPointerExceptionTest$B.to_c' of an object"); 184 } 185 } 186 187 public void testArrayChasing() { 188 int[][][][][] a = null; 189 try { 190 a[0][0][0][0][0] = 99; 191 Asserts.fail(); 192 } catch (NullPointerException e) { 193 checkMessage("int[0][0][0][0][0] = 99 // a is null", e.getMessage(), 194 "while trying to load from a null object array loaded from " + 195 (hasDebugInfo ? "local variable 'a'" : "a local variable at slot 1")); 196 } 197 a = new int[1][][][][]; 198 try { 199 a[0][0][0][0][0] = 99; 200 Asserts.fail(); 201 } catch (NullPointerException e) { 202 checkMessage("int[0][0][0][0][0] = 99 // a[0] is null", e.getMessage(), 203 "while trying to load from a null object array loaded from an array (which itself was loaded from " + 204 (hasDebugInfo ? "local variable 'a'" : "a local variable at slot 1") + 205 ") with an index loaded from a constant"); 206 } 207 a[0] = new int[1][][][]; 208 try { 209 a[0][0][0][0][0] = 99; 210 Asserts.fail(); 211 } catch (NullPointerException e) { 212 checkMessage("int[0][0][0][0][0] = 99 // a[0][0] is null", e.getMessage(), 213 "while trying to load from a null object array loaded from an array (which itself was loaded from an array) with an index loaded from a constant"); 214 } 215 a[0][0] = new int[1][][]; 216 try { 217 a[0][0][0][0][0] = 99; 218 Asserts.fail(); 219 } catch (NullPointerException e) { 220 checkMessage("int[0][0][0][0][0] = 99 // a[0][0][0] is null", e.getMessage(), 221 "while trying to load from a null object array loaded from an array (which itself was loaded from an array) with an index loaded from a constant"); 222 } 223 a[0][0][0] = new int[1][]; 224 try { 225 a[0][0][0][0][0] = 99; 226 Asserts.fail(); 227 } catch (NullPointerException e) { 228 checkMessage("int[0][0][0][0][0] = 99 // a[0][0][0][0] is null", e.getMessage(), 229 "while trying to store to a null int array loaded from an array (which itself was loaded from an array) with an index loaded from a constant"); 230 } 231 a[0][0][0][0] = new int[1]; 232 try { 233 a[0][0][0][0][0] = 99; 234 } catch (NullPointerException e) { 235 Asserts.fail(); 236 } 237 } 238 239 public void testMethodChasing() { 240 A a = null; 241 try { 242 a.getB().getBfromB().getC().getD().num = 99; 243 Asserts.fail(); 244 } catch (NullPointerException e) { 245 checkMessage("a.getB().getBfromB().getC().getD().num = 99 // a is null", e.getMessage(), 246 "while trying to invoke the method 'NullPointerExceptionTest$A.getB()LNullPointerExceptionTest$B;' on a null reference loaded from " + 247 (hasDebugInfo ? "local variable 'a'" : "a local variable at slot 1")); 248 } 249 a = new A(); 250 try { 251 a.getB().getBfromB().getC().getD().num = 99; 252 Asserts.fail(); 253 } catch (NullPointerException e) { 254 checkMessage("a.getB().getBfromB().getC().getD().num = 99 // a.getB() is null", e.getMessage(), 255 "while trying to invoke the method 'NullPointerExceptionTest$B.getBfromB()LNullPointerExceptionTest$B;' on a null reference returned from 'NullPointerExceptionTest$A.getB()LNullPointerExceptionTest$B;'"); 256 } 257 a.to_b = new B(); 258 try { 259 a.getB().getBfromB().getC().getD().num = 99; 260 Asserts.fail(); 261 } catch (NullPointerException e) { 262 checkMessage("a.getB().getBfromB().getC().getD().num = 99 // a.getB().getBfromB() is null", e.getMessage(), 263 "while trying to invoke the method 'NullPointerExceptionTest$B.getC()LNullPointerExceptionTest$C;' on a null reference returned from 'NullPointerExceptionTest$B.getBfromB()LNullPointerExceptionTest$B;'"); 264 } 265 a.to_b.to_b = new B(); 266 try { 267 a.getB().getBfromB().getC().getD().num = 99; 268 Asserts.fail(); 269 } catch (NullPointerException e) { 270 checkMessage("a.getB().getBfromB().getC().getD().num = 99 // a.getB().getBfromB().getC() is null", e.getMessage(), 271 "while trying to invoke the method 'NullPointerExceptionTest$C.getD()LNullPointerExceptionTest$D;' on a null reference returned from 'NullPointerExceptionTest$B.getC()LNullPointerExceptionTest$C;'"); 272 } 273 a.to_b.to_b.to_c = new C(); 274 try { 275 a.getB().getBfromB().getC().getD().num = 99; 276 Asserts.fail(); 277 } catch (NullPointerException e) { 278 checkMessage("a.getB().getBfromB().getC().getD().num = 99 // a.getB().getBfromB().getC().getD() is null", e.getMessage(), 279 "while trying to write the field 'NullPointerExceptionTest$D.num' of a null object returned from 'NullPointerExceptionTest$C.getD()LNullPointerExceptionTest$D;'"); 280 } 281 } 282 283 // Test we get the same message calling npe.getMessage() twice. 284 public void testSameMessage() throws Exception { 285 Object null_o = null; 286 String expectedMsg = 287 "while trying to invoke the method 'java.lang.Object.hashCode()I'" + 288 " on a null reference loaded from " + 289 (hasDebugInfo ? "local variable 'null_o'" : "a local variable at slot 1"); 290 291 try { 292 null_o.hashCode(); 293 Asserts.fail(); 294 } catch (NullPointerException npe) { 295 String msg1 = npe.getMessage(); 296 checkMessage("null_o.hashCode()", msg1, expectedMsg); 297 String msg2 = npe.getMessage(); 298 Asserts.assertTrue(msg1.equals(msg2)); 299 // It was decided that getMessage should generate the 300 // message anew on every call, so this does not hold any more. 301 Asserts.assertFalse(msg1 == msg2); 302 } 303 } 304 305 /** 306 * 307 */ 308 public void testCreationViaNew() { 309 Asserts.assertNull(new NullPointerException().getMessage()); 310 } 311 312 /** 313 * @throws Exception 314 */ 315 public void testCreationViaReflection() throws Exception { 316 Exception ex = NullPointerException.class.getDeclaredConstructor().newInstance(); 317 Asserts.assertNull(ex.getMessage()); 318 } 319 320 /** 321 * @throws Exception 322 */ 323 public void testCreationViaSerialization() throws Exception { 324 // NPE without message. 325 Object o1 = new NullPointerException(); 326 ByteArrayOutputStream bos1 = new ByteArrayOutputStream(); 327 ObjectOutputStream oos1 = new ObjectOutputStream(bos1); 328 oos1.writeObject(o1); 329 ByteArrayInputStream bis1 = new ByteArrayInputStream(bos1.toByteArray()); 330 ObjectInputStream ois1 = new ObjectInputStream(bis1); 331 Exception ex1 = (Exception) ois1.readObject(); 332 Asserts.assertNull(ex1.getMessage()); 333 334 // NPE with custom message. 335 String msg2 = "A useless message"; 336 Object o2 = new NullPointerException(msg2); 337 ByteArrayOutputStream bos2 = new ByteArrayOutputStream(); 338 ObjectOutputStream oos2 = new ObjectOutputStream(bos2); 339 oos2.writeObject(o2); 340 ByteArrayInputStream bis2 = new ByteArrayInputStream(bos2.toByteArray()); 341 ObjectInputStream ois2 = new ObjectInputStream(bis2); 342 Exception ex2 = (Exception) ois2.readObject(); 343 Asserts.assertEquals(ex2.getMessage(), msg2); 344 345 // NPE with generated message. 346 Object null_o3 = null; 347 Object o3 = null; 348 String msg3 = null; 349 try { 350 null_o3.hashCode(); 351 Asserts.fail(); 352 } catch (NullPointerException npe3) { 353 o3 = npe3; 354 msg3 = npe3.getMessage(); 355 checkMessage("null_o3.hashCode()", msg3, "while trying to invoke the method 'java.lang.Object.hashCode()I'" + 356 " on a null reference loaded from " + 357 (hasDebugInfo ? "local variable 'null_o3'" : "a local variable at slot 14")); 358 } 359 ByteArrayOutputStream bos3 = new ByteArrayOutputStream(); 360 ObjectOutputStream oos3 = new ObjectOutputStream(bos3); 361 oos3.writeObject(o3); 362 ByteArrayInputStream bis3 = new ByteArrayInputStream(bos3.toByteArray()); 363 ObjectInputStream ois3 = new ObjectInputStream(bis3); 364 Exception ex3 = (Exception) ois3.readObject(); 365 // It was decided that getMessage should not store the 366 // message in Throwable.detailMessage, thus it can not 367 // be recovered by serialization. 368 //Asserts.assertEquals(ex3.getMessage(), msg3); 369 Asserts.assertEquals(ex3.getMessage(), null); 370 } 371 372 /** 373 * 374 */ 375 @SuppressWarnings("null") 376 public void testLoadedFromLocalVariable1() { 377 Object o = null; 378 379 try { 380 o.hashCode(); 381 Asserts.fail(); 382 } catch (NullPointerException e) { 383 checkMessage("o.hashCode()", e.getMessage(), "while trying to invoke the method 'java.lang.Object.hashCode()I' on a null reference loaded from " + (hasDebugInfo ? "local variable 'o'" : "a local variable at slot 1")); 384 } 385 } 386 387 /** 388 * 389 */ 390 @SuppressWarnings("null") 391 public void testLoadedFromLocalVariable2() { 392 Exception[] myVariable = null; 393 394 try { 395 Asserts.assertNull(myVariable[0]); 396 Asserts.fail(); 397 } catch (NullPointerException e) { 398 checkMessage("myVariable[0]", e.getMessage(), "while trying to load from a null object array loaded from " + (hasDebugInfo ? "local variable 'myVariable'" : "a local variable at slot 1")); 399 } 400 } 401 402 /** 403 * 404 */ 405 @SuppressWarnings("null") 406 public void testLoadedFromLocalVariable3() { 407 Exception[] myVariable = null; 408 409 try { 410 myVariable[0] = null; 411 Asserts.fail(); 412 } catch (NullPointerException e) { 413 checkMessage("myVariable[0] = null", e.getMessage(), "while trying to store to a null object array loaded from " + (hasDebugInfo ? "local variable 'myVariable'" : "a local variable at slot 1")); 414 } 415 } 416 417 /** 418 * 419 */ 420 @SuppressWarnings("null") 421 public void testLoadedFromLocalVariable4() { 422 Exception[] myVariable\u0096 = null; 423 424 try { 425 Asserts.assertTrue(myVariable\u0096.length == 0); 426 Asserts.fail(); 427 } catch (NullPointerException e) { 428 checkMessage("myVariable\u0096.length", e.getMessage(), "while trying to get the length of a null array loaded from " + (hasDebugInfo ? "local variable 'myVariable'" : "a local variable at slot 1")); 429 } 430 } 431 432 /** 433 * @throws Exception 434 */ 435 @SuppressWarnings("null") 436 public void testLoadedFromLocalVariable5() throws Exception { 437 Exception myException = null; 438 439 try { 440 throw myException; 441 } catch (NullPointerException e) { 442 checkMessage("throw myException", e.getMessage(), "while trying to throw a null exception object loaded from " + (hasDebugInfo ? "local variable 'myException'" : "a local variable at slot 1")); 443 } 444 } 445 446 /** 447 * 448 */ 449 @SuppressWarnings("null") 450 public void testLoadedFromLocalVariable6() { 451 byte[] myVariable = null; 452 int my_index = 1; 453 454 try { 455 Asserts.assertTrue(myVariable[my_index] == 0); 456 Asserts.fail(); 457 } catch (NullPointerException e) { 458 checkMessage("myVariable[my_index]", e.getMessage(), "while trying to load from a null byte (or boolean) array loaded from " + (hasDebugInfo ? "local variable 'myVariable'" : "a local variable at slot 1")); 459 } 460 } 461 462 /** 463 * 464 */ 465 @SuppressWarnings("null") 466 public void testLoadedFromLocalVariable7() { 467 byte[] myVariable = null; 468 469 try { 470 myVariable[System.out.hashCode()] = (byte) 0; 471 Asserts.fail(); 472 } catch (NullPointerException e) { 473 checkMessage("myVariable[System.out.hashCode()]", e.getMessage(), "while trying to store to a null byte (or boolean) array loaded from " + (hasDebugInfo ? "local variable 'myVariable'" : "a local variable at slot 1")); 474 } 475 } 476 477 /** 478 * 479 */ 480 public void testLoadedFromMethod1() { 481 try { 482 Asserts.assertTrue(((char[]) NullPointerGenerator.nullReturner(false))[0] == 'A'); 483 Asserts.fail(); 484 } catch (NullPointerException e) { 485 checkMessage("((char[]) NullPointerGenerator.nullReturner(false))[0]", e.getMessage(), "while trying to load from a null char array returned from 'NullPointerExceptionTest$NullPointerGenerator.nullReturner(Z)Ljava/lang/Object;'"); 486 } 487 } 488 489 /** 490 * 491 */ 492 public void testLoadedFromMethod2() { 493 try { 494 Asserts.assertTrue(((char[]) (new NullPointerGenerator().returnMyNull(1, 1, (short) 1)))[0] == 'a'); 495 Asserts.fail(); 496 } catch (NullPointerException e) { 497 checkMessage("((char[]) (new NullPointerGenerator().returnMyNull(1, 1, (short) 1)))[0]", e.getMessage(), "while trying to load from a null char array returned from 'NullPointerExceptionTest$NullPointerGenerator.returnMyNull(DJS)Ljava/lang/Object;'"); 498 } 499 } 500 501 /** 502 * 503 */ 504 public void testLoadedFromMethod3() { 505 try { 506 Asserts.assertTrue(((double[]) returnNull(null, null, 1f))[0] == 1.0); 507 Asserts.fail(); 508 } catch (NullPointerException e) { 509 checkMessage("((double[]) returnNull(null, null, 1f))[0] ", e.getMessage(), "while trying to load from a null double array returned from 'NullPointerExceptionTest.returnNull([[Ljava/lang/String;[[[IF)Ljava/lang/Object;'"); 510 } 511 } 512 513 /** 514 * 515 */ 516 public void testLoadedFromMethod4() { 517 ImplTestLoadedFromMethod4(new DoubleArrayGenImpl()); 518 } 519 520 /** 521 * @param gen 522 */ 523 public void ImplTestLoadedFromMethod4(DoubleArrayGen gen) { 524 try { 525 (gen.getArray())[0] = 1.0; 526 Asserts.fail(); 527 } catch (NullPointerException e) { 528 checkMessage("(gen.getArray())[0]", e.getMessage(), "while trying to store to a null double array returned from 'NullPointerExceptionTest$DoubleArrayGen.getArray()[D'"); 529 } 530 } 531 532 /** 533 * 534 */ 535 public void testLoadedFromMethod5() { 536 try { 537 returnMeAsNull(null, 1, 'A').dag = null; 538 Asserts.fail(); 539 } catch (NullPointerException e) { 540 checkMessage("returnMeAsNull(null, 1, 'A').dag = null", e.getMessage(), "while trying to write the field 'NullPointerExceptionTest.dag' of a null object returned from 'NullPointerExceptionTest.returnMeAsNull(Ljava/lang/Throwable;IC)LNullPointerExceptionTest;'"); 541 } 542 /* 543 try { 544 returnMeAsNull(null, 1, 'A').dag.dag = null; 545 Asserts.fail(); 546 } catch (NullPointerException e) { 547 checkMessage("returnMeAsNull(null, 1, 'A').dag.dag = null", e.getMessage(), "while trying to write the field 'NullPointerExceptionTest.dag' of a null object returned from 'NullPointerExceptionTest.returnMeAsNull(Ljava/lang/Throwable;IC)LNullPointerExceptionTest;'"); 548 } 549 */ 550 } 551 552 /** 553 * 554 */ 555 @SuppressWarnings("null") 556 public void testLoadedFromMethod6() { 557 short[] sa = null; 558 559 try { 560 Asserts.assertTrue(sa[0] == (short) 1); 561 Asserts.fail(); 562 } catch (NullPointerException e) { 563 checkMessage("sa[0]", e.getMessage(), "while trying to load from a null short array loaded from " + (hasDebugInfo ? "local variable 'sa'" : "a local variable at slot 1")); 564 } 565 } 566 567 /** 568 * 569 */ 570 @SuppressWarnings("null") 571 public void testLoadedFromMethod7() { 572 short[] sa = null; 573 574 try { 575 sa[0] = 1; 576 Asserts.fail(); 577 } catch (NullPointerException e) { 578 checkMessage("sa[0] = 1", e.getMessage(), "while trying to store to a null short array loaded from " + (hasDebugInfo ? "local variable 'sa'" : "a local variable at slot 1")); 579 } 580 } 581 582 /** 583 * 584 */ 585 public void testLoadedFromStaticField1() { 586 try { 587 Asserts.assertTrue(((float[]) nullStaticField)[0] == 1.0f); 588 Asserts.fail(); 589 } catch (NullPointerException e) { 590 checkMessage("((float[]) nullStaticField)[0]", e.getMessage(), "while trying to load from a null float array loaded from static field 'NullPointerExceptionTest.nullStaticField'"); 591 } 592 } 593 594 /** 595 * 596 */ 597 public void testLoadedFromStaticField2() { 598 try { 599 ((float[]) nullStaticField)[0] = 1.0f; 600 Asserts.fail(); 601 } catch (NullPointerException e) { 602 checkMessage("((float[]) nullStaticField)[0] = 1.0f", e.getMessage(), "while trying to store to a null float array loaded from static field 'NullPointerExceptionTest.nullStaticField'"); 603 } 604 } 605 606 /** 607 * 608 */ 609 public void testLoadedFromStaticField3() { 610 try { 611 Asserts.assertTrue(staticArray[0][0][0][0] == 1); 612 Asserts.fail(); 613 } catch (NullPointerException e) { 614 checkMessage("staticArray[0][0][0][0] // staticArray[0][0][0] is null.", e.getMessage(), "while trying to load from a null int array loaded from an array (which itself was loaded from an array) with an index loaded from a constant"); 615 } 616 } 617 618 /** 619 * 620 */ 621 public void testLoadedFromStaticField4(int myIdx, int pos) { 622 try { 623 staticArray[0][0][pos][myIdx] = 2; 624 Asserts.fail(); 625 } catch (NullPointerException e) { 626 checkMessage(" staticArray[0][0][pos][myIdx] = 2", e.getMessage(), "while trying to store to a null int array loaded from an array (which itself was loaded from an array) with an index loaded from " + (hasDebugInfo ? "local variable 'pos'" : "the parameter nr. 2 of the method")); 627 } 628 } 629 630 /** 631 * 632 */ 633 public void testLoadedFromStaticField5() { 634 try { 635 Asserts.assertTrue(staticLongArray[0][0] == 1L); 636 } catch (NullPointerException e) { 637 checkMessage("staticLongArray[0][0]", e.getMessage(), "while trying to load from a null long array loaded from an array (which itself was loaded from static field 'NullPointerExceptionTest.staticLongArray') with an index loaded from a constant"); 638 } 639 } 640 641 /** 642 * Test bipush for index. 643 */ 644 public void testLoadedFromStaticField5a() { 645 try { 646 Asserts.assertTrue(staticLongArray[139 /*0x77*/][0] == 1L); 647 } catch (NullPointerException e) { 648 checkMessage("staticLongArray[139][0]", e.getMessage(), "while trying to load from a null long array loaded from an array (which itself was loaded from static field 'NullPointerExceptionTest.staticLongArray') with an index loaded from a constant"); 649 } 650 } 651 652 /** 653 * Test sipush for index. 654 */ 655 public void testLoadedFromStaticField5b() { 656 try { 657 Asserts.assertTrue(staticLongArray[819 /*0x333*/][0] == 1L); 658 } catch (NullPointerException e) { 659 checkMessage("staticLongArray[819][0]", e.getMessage(), "while trying to load from a null long array loaded from an array (which itself was loaded from static field 'NullPointerExceptionTest.staticLongArray') with an index loaded from a constant"); 660 } 661 } 662 663 /** 664 * 665 */ 666 public void testLoadedFromStaticField6() { 667 try { 668 staticLongArray[0][0] = 2L; 669 Asserts.fail(); 670 } catch (NullPointerException e) { 671 checkMessage("staticLongArray[0][0] = 2L", e.getMessage(), "while trying to store to a null long array loaded from an array (which itself was loaded from static field 'NullPointerExceptionTest.staticLongArray') with an index loaded from a constant"); 672 } 673 } 674 675 /** 676 * 677 */ 678 public void testLoadedFromInstanceField1() { 679 try { 680 Asserts.assertTrue(this.nullInstanceField.nullInstanceField == null); 681 Asserts.fail(); 682 } catch (NullPointerException e) { 683 checkMessage("this.nullInstanceField.nullInstanceField", e.getMessage(), "while trying to read the field 'nullInstanceField' of a null object loaded from field 'NullPointerExceptionTest.nullInstanceField' of an object loaded from 'this'"); 684 } 685 } 686 687 /** 688 * 689 */ 690 public void testLoadedFromInstanceField2() { 691 try { 692 this.nullInstanceField.nullInstanceField = null; 693 Asserts.fail(); 694 } catch (NullPointerException e) { 695 checkMessage("this.nullInstanceField.nullInstanceField = null", e.getMessage(), "while trying to write the field 'NullPointerExceptionTest.nullInstanceField' of a null object loaded from field 'NullPointerExceptionTest.nullInstanceField' of an object loaded from 'this'"); 696 } 697 } 698 699 /** 700 * 701 */ 702 public void testLoadedFromInstanceField3() { 703 NullPointerExceptionTest obj = this; 704 705 try { 706 Asserts.assertNull(obj.dag.getArray().clone()); 707 Asserts.fail(); 708 } catch (NullPointerException e) { 709 checkMessage("obj.dag.getArray().clone()", e.getMessage(), "while trying to invoke the method 'NullPointerExceptionTest$DoubleArrayGen.getArray()[D' on a null reference loaded from field 'NullPointerExceptionTest.dag' of an object loaded from " + (hasDebugInfo ? "local variable 'obj'" : "a local variable at slot 1")); 710 } 711 } 712 713 /** 714 * 715 */ 716 public void testLoadedFromInstanceField4() { 717 int indexes[] = new int[1]; 718 719 NullPointerExceptionTest[] objs = new NullPointerExceptionTest[] {this}; 720 721 try { 722 Asserts.assertNull(objs[indexes[0]].nullInstanceField.returnNull(null, null, 1f)); 723 Asserts.fail(); 724 } catch (NullPointerException e) { 725 checkMessage("objs[indexes[0]].nullInstanceField.returnNull(null, null, 1f", e.getMessage(), "while trying to invoke the method 'NullPointerExceptionTest.returnNull([[Ljava/lang/String;[[[IF)Ljava/lang/Object;' on a null reference loaded from field 'NullPointerExceptionTest.nullInstanceField' of an object loaded from an array"); 726 } 727 } 728 729 /** 730 * 731 */ 732 public void testLoadedFromInstanceField5() { 733 int indexes[] = new int[1]; 734 735 NullPointerExceptionTest[] objs = new NullPointerExceptionTest[] {this}; 736 737 try { 738 Asserts.assertNull(objs[indexes[0]].nullInstanceField.toString().toCharArray().clone()); 739 } catch (NullPointerException e) { 740 checkMessage("objs[indexes[0]].nullInstanceField.toString().toCharArray().clone()", e.getMessage(), "while trying to invoke the method 'java.lang.Object.toString()Ljava/lang/String;' on a null reference loaded from field 'NullPointerExceptionTest.nullInstanceField' of an object loaded from an array"); 741 } 742 } 743 744 /** 745 * 746 */ 747 public void testLoadedFromInstanceField6() { 748 int indexes[] = new int[1]; 749 750 NullPointerExceptionTest[][] objs = 751 new NullPointerExceptionTest[][] {new NullPointerExceptionTest[] {this}}; 752 753 try { 754 // Check monitorenter only, since we cannot probe monitorexit from Java. 755 synchronized (objs[indexes[0]][0].nullInstanceField) { 756 Asserts.fail(); 757 } 758 } catch (NullPointerException e) { 759 checkMessage("synchronized (objs[indexes[0]][0].nullInstanceField)", e.getMessage(), "while trying to enter a null monitor loaded from field 'NullPointerExceptionTest.nullInstanceField' of an object loaded from an array"); 760 } 761 } 762 763 /** 764 * @throws ClassNotFoundException 765 */ 766 public void testInNative() throws ClassNotFoundException { 767 try { 768 Class.forName(null); 769 Asserts.fail(); 770 } catch (NullPointerException e) { 771 Asserts.assertNull(e.getMessage()); 772 } 773 } 774 775 private Object returnNull(String[][] dummy1, int[][][] dummy2, float dummy3) { 776 return null; 777 } 778 779 private NullPointerExceptionTest returnMeAsNull(Throwable dummy1, int dummy2, char dummy3){ 780 return null; 781 } 782 783 static interface DoubleArrayGen { 784 public double[] getArray(); 785 } 786 787 static class DoubleArrayGenImpl implements DoubleArrayGen { 788 @Override 789 public double[] getArray() { 790 return null; 791 } 792 } 793 794 static class NullPointerGenerator { 795 public static Object nullReturner(boolean dummy1) { 796 return null; 797 } 798 799 public Object returnMyNull(double dummy1, long dummy2, short dummy3) { 800 return null; 801 } 802 } 803 804 /** 805 * 806 */ 807 public void testMissingLocalVariableTable() { 808 doTestMissingLocalVariableTable(names); 809 810 String[] expectedHasDebugInfoGoodNames = new String[] { 811 "while trying to invoke the method 'java.lang.Object.hashCode()I' on a null reference " + 812 "loaded from field 'NullPointerExceptionTest.nullInstanceField' " + 813 "of an object loaded from 'this'", 814 "while trying to invoke the method 'java.lang.Object.hashCode()I' on a null reference loaded from " + 815 "local variable 'a1'", 816 "while trying to invoke the method 'java.lang.Object.hashCode()I' on a null reference loaded from " + 817 "local variable 'o1'", 818 "while trying to invoke the method 'java.lang.Object.hashCode()I' on a null reference loaded from " + 819 "local variable 'aa1'" 820 }; 821 822 String[] expectedNoDebugInfoGoodNames = new String[] { 823 "while trying to invoke the method 'java.lang.Object.hashCode()I' on a null reference " + 824 "loaded from field 'NullPointerExceptionTest.nullInstanceField' " + 825 "of an object loaded from 'this'", 826 "while trying to invoke the method 'java.lang.Object.hashCode()I' on a null reference loaded from " + 827 "the parameter nr. 5 of the method", 828 "while trying to invoke the method 'java.lang.Object.hashCode()I' on a null reference loaded from " + 829 "the parameter nr. 2 of the method", 830 "while trying to invoke the method 'java.lang.Object.hashCode()I' on a null reference loaded from " + 831 "the parameter nr. 9 of the method" 832 }; 833 834 String[] expectedNames; 835 if (hasDebugInfo) { 836 expectedNames = expectedHasDebugInfoGoodNames; 837 } else { 838 expectedNames = expectedNoDebugInfoGoodNames; 839 } 840 841 // The two lists of messages should have the same length. 842 Asserts.assertEquals(names.size(), expectedNames.length); 843 844 for (int i = 0; i < expectedNames.length; ++i) { 845 // GLGLGL not for now Asserts.assertEquals(names.get(i), expectedNames[i]); 846 } 847 } 848 849 private void doTestMissingLocalVariableTable(ArrayList<String> names) { 850 curr = names; 851 doTestMissingLocalVariableTable1(); 852 doTestMissingLocalVariableTable2(-1, null, false, 0.0, null, 0.1f, (byte) 0, (short) 0, null); 853 } 854 855 private void doTestMissingLocalVariableTable1() { 856 try { 857 this.nullInstanceField.hashCode(); 858 Asserts.fail(); 859 } catch (NullPointerException e) { 860 curr.add(e.getMessage()); 861 } 862 } 863 864 private void doTestMissingLocalVariableTable2(long l1, Object o1, boolean z1, double d1, Object[] a1, 865 float f1, byte b1, short s1, Object[][] aa1) { 866 try { 867 a1.hashCode(); 868 Asserts.fail(); 869 } 870 catch (NullPointerException e) { 871 curr.add(e.getMessage()); 872 } 873 874 try { 875 o1.hashCode(); 876 Asserts.fail(); 877 } 878 catch (NullPointerException e) { 879 curr.add(e.getMessage()); 880 } 881 882 try { 883 aa1.hashCode(); 884 Asserts.fail(); 885 } 886 catch (NullPointerException e) { 887 curr.add(e.getMessage()); 888 } 889 } 890 891 /** 892 * 893 */ 894 @SuppressWarnings("null") 895 public void testNullMessages() { 896 boolean[] za1 = null; 897 byte[] ba1 = null; 898 short[] sa1 = null; 899 char[] ca1 = null; 900 int[] ia1 = null; 901 long[] la1 = null; 902 float[] fa1 = null; 903 double[] da1 = null; 904 Object[] oa1 = null; 905 906 Object[][] oa2 = new Object[2][]; 907 oa2[1] = oa1; 908 909 try { 910 System.out.println(oa2[1][0]); 911 Asserts.fail(); 912 } catch (NullPointerException e) { 913 checkMessage("oa2[1][0]", e.getMessage(), 914 "while trying to load from a null object array loaded from an array " + 915 "(which itself was loaded from " + 916 (hasDebugInfo ? "local variable 'oa2'" : "a local variable at slot 10") + ") " + 917 "with an index loaded from a constant"); 918 } 919 920 921 try { 922 System.out.println(za1[0]); 923 Asserts.fail(); 924 } catch (NullPointerException e) { 925 checkMessage("za1[0]", e.getMessage(), 926 "while trying to load from a null byte (or boolean) array loaded from " + 927 (hasDebugInfo ? "local variable 'za1'" : "a local variable at slot 1")); 928 } 929 930 try { 931 System.out.println(ba1[0]); 932 Asserts.fail(); 933 } catch (NullPointerException e) { 934 checkMessage("ba1[0]", e.getMessage(), 935 "while trying to load from a null byte (or boolean) array loaded from " + 936 (hasDebugInfo ? "local variable 'ba1'" : "a local variable at slot 2")); 937 } 938 939 try { 940 System.out.println(sa1[0]); 941 Asserts.fail(); 942 } catch (NullPointerException e) { 943 checkMessage("sa1[0]", e.getMessage(), 944 "while trying to load from a null short array loaded from " + 945 (hasDebugInfo ? "local variable 'sa1'" : "a local variable at slot 3")); 946 } 947 948 try { 949 System.out.println(ca1[0]); 950 Asserts.fail(); 951 } catch (NullPointerException e) { 952 checkMessage("ca1[0]", e.getMessage(), 953 "while trying to load from a null char array loaded from " + 954 (hasDebugInfo ? "local variable 'ca1'" : "a local variable at slot 4")); 955 } 956 957 try { 958 System.out.println(ia1[0]); 959 Asserts.fail(); 960 } catch (NullPointerException e) { 961 checkMessage("ia1[0]", e.getMessage(), 962 "while trying to load from a null int array loaded from " + 963 (hasDebugInfo ? "local variable 'ia1'" : "a local variable at slot 5")); 964 } 965 966 try { 967 System.out.println(la1[0]); 968 Asserts.fail(); 969 } catch (NullPointerException e) { 970 checkMessage("la1[0]", e.getMessage(), 971 "while trying to load from a null long array loaded from " + 972 (hasDebugInfo ? "local variable 'la1'" : "a local variable at slot 6")); 973 } 974 975 try { 976 System.out.println(fa1[0]); 977 Asserts.fail(); 978 } catch (NullPointerException e) { 979 checkMessage("fa1[0]", e.getMessage(), 980 "while trying to load from a null float array loaded from " + 981 (hasDebugInfo ? "local variable 'fa1'" : "a local variable at slot 7")); 982 } 983 984 try { 985 System.out.println(da1[0]); 986 Asserts.fail(); 987 } catch (NullPointerException e) { 988 checkMessage("da1[0]", e.getMessage(), 989 "while trying to load from a null double array loaded from " + 990 (hasDebugInfo ? "local variable 'da1'" : "a local variable at slot 8")); 991 } 992 993 try { 994 System.out.println(oa1[0]); 995 Asserts.fail(); 996 } catch (NullPointerException e) { 997 checkMessage("oa1[0]", e.getMessage(), 998 "while trying to load from a null object array loaded from " + 999 (hasDebugInfo ? "local variable 'oa1'" : "a local variable at slot 9")); 1000 } 1001 1002 try { 1003 System.out.println(za1[0] = false); 1004 Asserts.fail(); 1005 } catch (NullPointerException e) { 1006 checkMessage("za1[0] = false", e.getMessage(), 1007 "while trying to store to a null byte (or boolean) array loaded from " + 1008 (hasDebugInfo ? "local variable 'za1'" : "a local variable at slot 1")); 1009 } 1010 1011 try { 1012 System.out.println(ba1[0] = 0); 1013 Asserts.fail(); 1014 } catch (NullPointerException e) { 1015 checkMessage("ba1[0] = 0", e.getMessage(), 1016 "while trying to store to a null byte (or boolean) array loaded from " + 1017 (hasDebugInfo ? "local variable 'ba1'" : "a local variable at slot 2")); 1018 } 1019 1020 try { 1021 System.out.println(sa1[0] = 0); 1022 Asserts.fail(); 1023 } catch (NullPointerException e) { 1024 checkMessage("sa1[0] = 0", e.getMessage(), 1025 "while trying to store to a null short array loaded from " + 1026 (hasDebugInfo ? "local variable 'sa1'" : "a local variable at slot 3")); 1027 } 1028 1029 try { 1030 System.out.println(ca1[0] = 0); 1031 Asserts.fail(); 1032 } catch (NullPointerException e) { 1033 checkMessage("ca1[0] = 0", e.getMessage(), 1034 "while trying to store to a null char array loaded from " + 1035 (hasDebugInfo ? "local variable 'ca1'" : "a local variable at slot 4")); 1036 } 1037 1038 try { 1039 System.out.println(ia1[0] = 0); 1040 Asserts.fail(); 1041 } catch (NullPointerException e) { 1042 checkMessage("ia1[0] = 0", e.getMessage(), 1043 "while trying to store to a null int array loaded from " + 1044 (hasDebugInfo ? "local variable 'ia1'" : "a local variable at slot 5")); 1045 } 1046 1047 try { 1048 System.out.println(la1[0] = 0); 1049 Asserts.fail(); 1050 } catch (NullPointerException e) { 1051 checkMessage("la1[0] = 0", e.getMessage(), 1052 "while trying to store to a null long array loaded from " + 1053 (hasDebugInfo ? "local variable 'la1'" : "a local variable at slot 6")); 1054 } 1055 1056 try { 1057 System.out.println(fa1[0] = 0); 1058 Asserts.fail(); 1059 } catch (NullPointerException e) { 1060 checkMessage("fa1[0] = 0", e.getMessage(), 1061 "while trying to store to a null float array loaded from " + 1062 (hasDebugInfo ? "local variable 'fa1'" : "a local variable at slot 7")); 1063 } 1064 1065 try { 1066 System.out.println(da1[0] = 0); 1067 Asserts.fail(); 1068 } catch (NullPointerException e) { 1069 checkMessage("da1[0] = 0", e.getMessage(), 1070 "while trying to store to a null double array loaded from " + 1071 (hasDebugInfo ? "local variable 'da1'" : "a local variable at slot 8")); 1072 } 1073 1074 try { 1075 System.out.println(oa1[0] = null); 1076 Asserts.fail(); 1077 } catch (NullPointerException e) { 1078 checkMessage("oa1[0] = null", e.getMessage(), 1079 "while trying to store to a null object array loaded from " + 1080 (hasDebugInfo ? "local variable 'oa1'" : "a local variable at slot 9")); 1081 } 1082 1083 try { 1084 System.out.println(nullInstanceField.nullInstanceField); 1085 Asserts.fail(); 1086 } catch (NullPointerException e) { 1087 checkMessage("nullInstanceField.nullInstanceField", e.getMessage(), 1088 "while trying to read the field 'nullInstanceField' of a null object loaded " + 1089 "from field 'NullPointerExceptionTest.nullInstanceField' of an object " + 1090 "loaded from 'this'"); 1091 } 1092 1093 try { 1094 System.out.println(nullInstanceField.nullInstanceField = null); 1095 Asserts.fail(); 1096 } catch (NullPointerException e) { 1097 checkMessage("nullInstanceField.nullInstanceField = null", e.getMessage(), 1098 "while trying to write the field 'NullPointerExceptionTest.nullInstanceField' " + 1099 "of a null object loaded from field 'NullPointerExceptionTest.nullInstanceField' " + 1100 "of an object loaded from 'this'"); 1101 } 1102 1103 try { 1104 System.out.println(za1.length); 1105 Asserts.fail(); 1106 } catch (NullPointerException e) { 1107 checkMessage("za1.length", e.getMessage(), 1108 "while trying to get the length of a null array loaded from " + 1109 (hasDebugInfo ? "local variable 'za1'" : "a local variable at slot 1")); 1110 } 1111 1112 try { 1113 throw null; 1114 } catch (NullPointerException e) { 1115 checkMessage("throw null", e.getMessage(), 1116 "while trying to throw a null exception object loaded " + 1117 "from a constant"); 1118 } 1119 1120 try { 1121 synchronized (nullInstanceField) { 1122 // desired 1123 } 1124 } catch (NullPointerException e) { 1125 checkMessage("synchronized (nullInstanceField)", e.getMessage(), 1126 "while trying to enter a null monitor loaded from field " + 1127 "'NullPointerExceptionTest.nullInstanceField' of an object loaded from " + 1128 "'this'"); 1129 } 1130 1131 try { 1132 nullInstanceField.testCreationViaNew(); 1133 Asserts.fail(); 1134 } catch (NullPointerException e) { 1135 checkMessage("nullInstanceField.testCreationViaNew()", e.getMessage(), 1136 "while trying to invoke the method 'NullPointerExceptionTest.testCreationViaNew()V' on a null reference " + 1137 "loaded from field 'NullPointerExceptionTest.nullInstanceField' of an " + 1138 "object loaded from 'this'"); 1139 } 1140 1141 try { 1142 nullInstanceField.testNullMessages(); 1143 Asserts.fail(); 1144 } catch (NullPointerException e) { 1145 checkMessage("nullInstanceField.testNullMessages()", e.getMessage(), 1146 "while trying to invoke the method 'NullPointerExceptionTest.testNullMessages()V' on a null reference " + 1147 "loaded from field 'NullPointerExceptionTest.nullInstanceField' of an " + 1148 "object loaded from 'this'"); 1149 } 1150 1151 try { 1152 // If we can get the value from more than one bci, we cannot know which one. 1153 (Math.random() < 0.5 ? oa1 : (new Object[1])[0]).equals(""); 1154 } catch (NullPointerException e) { 1155 checkMessage("(Math.random() < 0.5 ? oa1 : (new Object[1])[0]).equals(\"\")", e.getMessage(), 1156 "while trying to invoke the method 'java.lang.Object.equals(Ljava/lang/Object;)Z' on a null reference"); 1157 } 1158 } 1159 }