diff -r cb67307942f3 -r aa400d41ebd6 test/hotspot/jtreg/runtime/exceptionMsgs/NullPointerException/NullPointerExceptionTest.java --- a/test/hotspot/jtreg/runtime/exceptionMsgs/NullPointerException/NullPointerExceptionTest.java Wed Apr 10 08:15:45 2019 +0200 +++ b/test/hotspot/jtreg/runtime/exceptionMsgs/NullPointerException/NullPointerExceptionTest.java Wed Apr 10 08:26:23 2019 +0200 @@ -27,6 +27,8 @@ * @summary Test extended NullPointerException message for class * files generated without debugging information. The message lists * detailed information about the entity that is null. + * @modules java.base/java.lang:open + * java.base/jdk.internal.org.objectweb.asm * @library /test/lib * @compile NullPointerExceptionTest.java * @run main NullPointerExceptionTest @@ -36,9 +38,11 @@ * @summary Test extended NullPointerException message for * classfiles generated with debug information. In this case the name * of the variable containing the array is printed. + * @modules java.base/java.lang:open + * java.base/jdk.internal.org.objectweb.asm * @library /test/lib * @compile -g NullPointerExceptionTest.java - * @run main/othervm -XX:+WizardMode -DhasDebugInfo NullPointerExceptionTest + * @run main/othervm -XX:+WizardMode NullPointerExceptionTest hasDebugInfo */ import java.io.ByteArrayInputStream; @@ -49,10 +53,22 @@ import jdk.test.lib.Asserts; +import java.lang.reflect.*; +import java.lang.invoke.MethodHandles.Lookup; +import static java.lang.invoke.MethodHandles.*; +import static java.lang.invoke.MethodHandles.Lookup.*; + +import jdk.internal.org.objectweb.asm.ClassWriter; +import jdk.internal.org.objectweb.asm.MethodVisitor; +import jdk.internal.org.objectweb.asm.Type; +import jdk.internal.org.objectweb.asm.Label; +import static jdk.internal.org.objectweb.asm.Opcodes.*; + /** * Tests NullPointerExceptions */ public class NullPointerExceptionTest { + // Some fields used in the test. static Object nullStaticField; NullPointerExceptionTest nullInstanceField; @@ -61,15 +77,9 @@ DoubleArrayGen dag; ArrayList names = new ArrayList<>(); ArrayList curr; - static boolean hasDebugInfo = true; + static boolean hasDebugInfo = false; static { - try { - hasDebugInfo = System.getProperty("hasDebugInfo") != null; - } catch (Throwable t) { - throw new RuntimeException(t); - } - staticArray = new int[1][][][]; staticArray[0] = new int[1][][]; staticArray[0][0] = new int[1][]; @@ -80,58 +90,537 @@ System.out.println(); System.out.println(" source code: " + expression); System.out.println(" thrown msg: " + obtainedMsg); - //System.out.println("expected msg: " + expectedMsg); - //Asserts.assertEquals(obtainedMsg, expectedMsg); + if (obtainedMsg.equals(expectedMsg)) return; + System.out.println("expected msg: " + expectedMsg); + Asserts.assertEquals(obtainedMsg, expectedMsg); } public static void main(String[] args) throws Exception { NullPointerExceptionTest t = new NullPointerExceptionTest(); - t.testPointerChasing(); - t.testArrayChasing(); - t.testMethodChasing(); - t.testMixedChasing(); + if (args.length > 0) { + hasDebugInfo = true; + } + + // Test the message printed for the failed action. + t.testFailedAction(); + + // Test the method printed for the null entity. + t.testNullEntity(); + + // Test that no message is printed for exceptions + // allocated explicitly. + t.testCreation(); + + // Test that no message is printed for exceptions + // thrown in native methods. + t.testNative(); + + // Test that two calls to getMessage() return the same + // message. + // It is a design decision that it returns two different + // String objects. t.testSameMessage(); - t.testCreationViaNew(); - t.testCreationViaReflection(); - t.testCreationViaSerialization(); - t.testLoadedFromLocalVariable1(); - t.testLoadedFromLocalVariable2(); - t.testLoadedFromLocalVariable3(); - t.testLoadedFromLocalVariable4(); - t.testLoadedFromLocalVariable5(); - t.testLoadedFromLocalVariable6(); - t.testLoadedFromLocalVariable7(); - t.testLoadedFromMethod1(); - t.testLoadedFromMethod2(); - t.testLoadedFromMethod3(); - t.testLoadedFromMethod4(); - t.testLoadedFromMethod5(); - t.testLoadedFromMethod6(); - t.testLoadedFromMethod7(); - t.testLoadedFromStaticField1(); - t.testLoadedFromStaticField2(); - t.testLoadedFromStaticField3(); - t.testLoadedFromStaticField4(0, 0); - t.testLoadedFromStaticField5(); - t.testLoadedFromStaticField5a(); - t.testLoadedFromStaticField5b(); - t.testLoadedFromStaticField6(); - t.testLoadedFromInstanceField1(); - t.testLoadedFromInstanceField2(); - t.testLoadedFromInstanceField3(); - t.testLoadedFromInstanceField4(); - t.testLoadedFromInstanceField5(); - t.testLoadedFromInstanceField6(); - t.testInNative(); - t.testMissingLocalVariableTable(); - t.testNullMessages(); + + // Test serialization. + // It is a design decision that after serialization the + // the message is lost. + t.testSerialization(); + + // Test that messages are printed for code generated + // on-the-fly. + t.testGeneratedCode(); + + + // Some more interesting complex messages. + t.testComplexMessages(); + } + + // Helper method to cause test case. + private double callWithTypes(String[][] dummy1, int[][][] dummy2, float dummy3, long dummy4, short dummy5, + boolean dummy6, byte dummy7, double dummy8, char dummy9) { + return 0.0; } + public void testFailedAction() { + int[] ia1 = null; + float[] fa1 = null; + Object[] oa1 = null; + boolean[] za1 = null; + byte[] ba1 = null; + char[] ca1 = null; + short[] sa1 = null; + long[] la1 = null; + double[] da1 = null; + + // iaload + try { + System.out.println(ia1[0]); + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("ia1[0]", e.getMessage(), + (hasDebugInfo ? "'ia1'" : "''") + " is null. " + + "Can not load from null int array."); + } + // faload + try { + System.out.println(fa1[0]); + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("fa1[0]", e.getMessage(), + (hasDebugInfo ? "'fa1'" : "''") + " is null. " + + "Can not load from null float array."); + } + // aaload + try { + System.out.println(oa1[0]); + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("oa1[0]", e.getMessage(), + (hasDebugInfo ? "'oa1'" : "''") + " is null. " + + "Can not load from null object array."); + } + // baload (boolean) + try { + System.out.println(za1[0]); + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("za1[0]", e.getMessage(), + (hasDebugInfo ? "'za1'" : "''") + " is null. " + + "Can not load from null byte/boolean array."); + } + // baload (byte) + try { + System.out.println(ba1[0]); + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("ba1[0]", e.getMessage(), + (hasDebugInfo ? "'ba1'" : "''") + " is null. " + + "Can not load from null byte/boolean array."); + } + // caload + try { + System.out.println(ca1[0]); + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("ca1[0]", e.getMessage(), + (hasDebugInfo ? "'ca1'" : "''") + " is null. " + + "Can not load from null char array."); + } + // saload + try { + System.out.println(sa1[0]); + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("sa1[0]", e.getMessage(), + (hasDebugInfo ? "'sa1'" : "''") + " is null. " + + "Can not load from null short array."); + } + // laload + try { + System.out.println(la1[0]); + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("la1[0]", e.getMessage(), + (hasDebugInfo ? "'la1'" : "''") + " is null. " + + "Can not load from null long array."); + } + // daload + try { + System.out.println(da1[0]); + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("da1[0]", e.getMessage(), + (hasDebugInfo ? "'da1'" : "''") + " is null. " + + "Can not load from null double array."); + } + + // iastore + try { + System.out.println(ia1[0] = 0); + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("ia1[0] = 0", e.getMessage(), + (hasDebugInfo ? "'ia1'" : "''") + " is null. " + + "Can not store to null int array."); + } + // fastore + try { + System.out.println(fa1[0] = 0.7f); + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("fa1[0] = false", e.getMessage(), + (hasDebugInfo ? "'fa1'" : "''") + " is null. " + + "Can not store to null float array."); + } + // aastore + try { + System.out.println(oa1[0] = null); + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("oa1[0] = null", e.getMessage(), + (hasDebugInfo ? "'oa1'" : "''") + " is null. " + + "Can not store to null object array."); + } + // bastore (boolean) + try { + System.out.println(za1[0] = false); + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("za1[0] = false", e.getMessage(), + (hasDebugInfo ? "'za1'" : "''") + " is null. " + + "Can not store to null byte/boolean array."); + } + // bastore (byte) + try { + System.out.println(ba1[0] = 0); + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("ba1[0] = 0", e.getMessage(), + (hasDebugInfo ? "'ba1'" : "''") + " is null. " + + "Can not store to null byte/boolean array."); + } + // castore + try { + System.out.println(ca1[0] = 0); + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("ca1[0] = 0", e.getMessage(), + (hasDebugInfo ? "'ca1'" : "''") + " is null. " + + "Can not store to null char array."); + } + // sastore + try { + System.out.println(sa1[0] = 0); + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("sa1[0] = 0", e.getMessage(), + (hasDebugInfo ? "'sa1'" : "''") + " is null. " + + "Can not store to null short array."); + } + // lastore + try { + System.out.println(la1[0] = 0); + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("la1[0] = 0", e.getMessage(), + (hasDebugInfo ? "'la1'" : "''") + " is null. " + + "Can not store to null long array."); + } + // dastore + try { + System.out.println(da1[0] = 0); + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("da1[0] = 0", e.getMessage(), + (hasDebugInfo ? "'da1'" : "''") + " is null. " + + "Can not store to null double array."); + } + + // arraylength + try { + System.out.println(za1.length); + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("za1.length", e.getMessage(), + (hasDebugInfo ? "'za1'" : "''") + " is null. " + + "Can not read the array length."); + } + // athrow + try { + throw null; + } catch (NullPointerException e) { + checkMessage("throw null", e.getMessage(), + "'null' is null. " + + "Can not throw a null exception object."); + } + // monitorenter + try { + synchronized (nullInstanceField) { + // desired + } + } catch (NullPointerException e) { + checkMessage("synchronized (nullInstanceField)", e.getMessage(), + "'this.nullInstanceField' is null. " + + "Can not enter a null monitor."); + } + // monitorexit + // No test available + + // getfield + try { + System.out.println(nullInstanceField.nullInstanceField); + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("nullInstanceField.nullInstanceField", e.getMessage(), + "'this.nullInstanceField' is null. " + + "Can not read field 'nullInstanceField'."); + } + // putfield + try { + System.out.println(nullInstanceField.nullInstanceField = null); + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("nullInstanceField.nullInstanceField = null", e.getMessage(), + "'this.nullInstanceField' is null. " + + "Can not write field 'nullInstanceField'."); + } + // invoke + try { + nullInstanceField.toString(); + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("nullInstanceField.toString()", e.getMessage(), + "'this.nullInstanceField' is null. " + + "Can not invoke method 'java.lang.String java.lang.Object.toString()'."); + } + // Test parameter and return types + try { + Asserts.assertTrue(nullInstanceField.callWithTypes(null, null, 0.0f, 0L, (short)0, false, (byte)0, 0.0, 'x') == 0.0); + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("nullInstanceField.callWithTypes(null, null, 0.0f, 0L, (short)0, false, (byte)0, 0.0, 'x')", e.getMessage(), + "'this.nullInstanceField' is null. " + + "Can not invoke method 'double NullPointerExceptionTest.callWithTypes(java.lang.String[][], int[][][], float, long, short, boolean, byte, double, char)'."); + } + } + + static void test_iload() { + int i0 = 0; + int i1 = 1; + int i2 = 2; + int i3 = 3; + int i4 = 4; + int i5 = 5; + + int[][] a = new int[6][]; + + // iload_0 + try { + a[i0][0] = 77; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("a[i0][0]", e.getMessage(), + (hasDebugInfo ? "'a[i0]'" : "'[]'") + " is null. " + + "Can not store to null int array."); + } + // iload_1 + try { + a[i1][0] = 77; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("a[i1][0]", e.getMessage(), + (hasDebugInfo ? "'a[i1]'" : "'[]'") + " is null. " + + "Can not store to null int array."); + } + // iload_2 + try { + a[i2][0] = 77; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("a[i2][0]", e.getMessage(), + (hasDebugInfo ? "'a[i2]'" : "'[]'") + " is null. " + + "Can not store to null int array."); + } + // iload_3 + try { + a[i3][0] = 77; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("a[i3][0]", e.getMessage(), + (hasDebugInfo ? "'a[i3]'" : "'[]'") + " is null. " + + "Can not store to null int array."); + } + // iload + try { + a[i5][0] = 77; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("a[i5][0]", e.getMessage(), + (hasDebugInfo ? "'a[i5]'" : "'[]'") + " is null. " + + "Can not store to null int array."); + } + } + + // Other datatyes than int are not needed. + // If we implement l2d and similar bytecodes, we can print + // long expressions as array indexes. Then these here could + // be used. + static void test_lload() { + long l0 = 0L; + long l1 = 1L; + long l2 = 2L; + long l3 = 3L; + long l4 = 4L; + long l5 = 5L; + + int[][] a = new int[6][]; + + // lload_0 + try { + a[(int)l0][0] = 77; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("a[(int)l0][0]", e.getMessage(), + (hasDebugInfo ? "'a[...]'" : "'[...]'") + " is null. " + + "Can not store to null int array."); + } + // lload_1 + try { + a[(int)l1][0] = 77; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("a[(int)l1][0]", e.getMessage(), + (hasDebugInfo ? "'a[...]'" : "'[...]'") + " is null. " + + "Can not store to null int array."); + } + // lload_2 + try { + a[(int)l2][0] = 77; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("a[(int)l2][0]", e.getMessage(), + (hasDebugInfo ? "'a[...]'" : "'[...]'") + " is null. " + + "Can not store to null int array."); + } + // lload_3 + try { + a[(int)l3][0] = 77; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("a[(int)l3][0]", e.getMessage(), + (hasDebugInfo ? "'a[...]'" : "'[...]'") + " is null. " + + "Can not store to null int array."); + } + // lload + try { + a[(int)l5][0] = 77; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("a[(int)l5][0]", e.getMessage(), + (hasDebugInfo ? "'a[...]'" : "'[...]'") + " is null. " + + "Can not store to null int array."); + } + } + + static void test_fload() { + float f0 = 0.0f; + float f1 = 1.0f; + float f2 = 2.0f; + float f3 = 3.0f; + float f4 = 4.0f; + float f5 = 5.0f; + + int[][] a = new int[6][]; + + // fload_0 + try { + a[(int)f0][0] = 77; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("a[(int)f0][0]", e.getMessage(), + (hasDebugInfo ? "'a[...]'" : "'[...]'") + " is null. " + + "Can not store to null int array."); + } + // fload_1 + try { + a[(int)f1][0] = 77; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("a[(int)f1][0]", e.getMessage(), + (hasDebugInfo ? "'a[...]'" : "'[...]'") + " is null. " + + "Can not store to null int array."); + } + // fload_2 + try { + a[(int)f2][0] = 77; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("a[(int)f2][0]", e.getMessage(), + (hasDebugInfo ? "'a[...]'" : "'[...]'") + " is null. " + + "Can not store to null int array."); + } + // fload_3 + try { + a[(int)f3][0] = 77; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("a[(int)f3][0]", e.getMessage(), + (hasDebugInfo ? "'a[...]'" : "'[...]'") + " is null. " + + "Can not store to null int array."); + } + // fload + try { + a[(int)f5][0] = 77; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("a[(int)f5][0]", e.getMessage(), + (hasDebugInfo ? "'a[...]'" : "'[...]'") + " is null. " + + "Can not store to null int array."); + } + } + + static void test_aload() { + F f0 = null; + F f1 = null; + F f2 = null; + F f3 = null; + F f4 = null; + F f5 = null; + + // aload_0 + try { + f0.i = 33; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("f0.i", e.getMessage(), + (hasDebugInfo ? "'f0'" : "''") + " is null. " + + "Can not write field 'i'."); + } + // aload_1 + try { + f1.i = 33; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("f1.i", e.getMessage(), + (hasDebugInfo ? "'f1'" : "''") + " is null. " + + "Can not write field 'i'."); + } + // aload_2 + try { + f2.i = 33; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("f2.i", e.getMessage(), + (hasDebugInfo ? "'f2'" : "''") + " is null. " + + "Can not write field 'i'."); + } + // aload_3 + try { + f3.i = 33; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("f3.i", e.getMessage(), + (hasDebugInfo ? "'f3'" : "''") + " is null. " + + "Can not write field 'i'."); + } + // aload + try { + f5.i = 33; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("f5.i", e.getMessage(), + (hasDebugInfo ? "'f5'" : "''") + " is null. " + + "Can not write field 'i'."); + } + } + + // Helper class for test cases. class A { public B to_b; public B getB() { return to_b; } } + // Helper class for test cases. class B { public C to_c; public B to_b; @@ -139,16 +628,83 @@ public B getBfromB() { return to_b; } } + // Helper class for test cases. class C { public D to_d; public D getD() { return to_d; } } + // Helper class for test cases. class D { public int num; public int[][] ar; } + + public void testArrayChasing() { + int[][][][][][] a = null; + try { + a[0][0][0][0][0][0] = 99; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("int[0][0][0][0][0] = 99 // a is null", e.getMessage(), + (hasDebugInfo ? "'a'" : "''") + " is null. " + + "Can not load from null object array."); + } + a = new int[1][][][][][]; + try { + a[0][0][0][0][0][0] = 99; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("int[0][0][0][0][0] = 99 // a[0] is null", e.getMessage(), + (hasDebugInfo ? "'a[0]'" : "'[0]'") + " is null. " + + "Can not load from null object array."); + } + a[0] = new int[1][][][][]; + try { + a[0][0][0][0][0][0] = 99; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("int[0][0][0][0][0] = 99 // a[0][0] is null", e.getMessage(), + (hasDebugInfo ? "'a[0][0]'" : "'[0][0]'") + " is null. " + + "Can not load from null object array."); + } + a[0][0] = new int[1][][][]; + try { + a[0][0][0][0][0][0] = 99; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("int[0][0][0][0][0] = 99 // a[0][0][0] is null", e.getMessage(), + (hasDebugInfo ? "'a[0][0][0]'" : "'[0][0][0]'") + " is null. " + + "Can not load from null object array."); + } + a[0][0][0] = new int[1][][]; + try { + a[0][0][0][0][0][0] = 99; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("int[0][0][0][0][0] = 99 // a[0][0][0][0] is null", e.getMessage(), + (hasDebugInfo ? "'a[0][0][0][0]'" : "'[0][0][0][0]'") + " is null. " + + "Can not load from null object array."); + } + a[0][0][0][0] = new int[1][]; + // Reaching max recursion depth. Prints . + try { + a[0][0][0][0][0][0] = 99; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("int[0][0][0][0][0] = 99 // a[0][0][0][0][0] is null", e.getMessage(), + "'[0][0][0][0][0]' is null. " + + "Can not store to null int array."); + } + a[0][0][0][0][0] = new int[1]; + try { + a[0][0][0][0][0][0] = 99; + } catch (NullPointerException e) { + Asserts.fail(); + } + } + public void testPointerChasing() { A a = null; try { @@ -156,8 +712,8 @@ Asserts.fail(); } catch (NullPointerException e) { checkMessage("a.to_b.to_c.to_d.num = 99 // a is null", e.getMessage(), - "while trying to read the field 'to_b' of a null object loaded from " + - (hasDebugInfo ? "local variable 'a'" : "a local variable at slot 1")); + (hasDebugInfo ? "'a'" : "''") + " is null. " + + "Can not read field 'to_b'."); } a = new A(); try { @@ -165,8 +721,8 @@ Asserts.fail(); } catch (NullPointerException e) { checkMessage("a.to_b.to_c.to_d.num = 99 // a.to_b is null", e.getMessage(), - "while trying to read the field 'to_c' of a null object loaded from field 'NullPointerExceptionTest$A.to_b' of an object loaded from " + - (hasDebugInfo ? "local variable 'a'" : "a local variable at slot 1")); + (hasDebugInfo ? "'a.to_b'" : "'.to_b'") + " is null. " + + "Can not read field 'to_c'."); } a.to_b = new B(); try { @@ -174,7 +730,8 @@ Asserts.fail(); } catch (NullPointerException e) { checkMessage("a.to_b.to_c.to_d.num = 99 // a.to_b.to_c is null", e.getMessage(), - "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"); + (hasDebugInfo ? "'a.to_b.to_c'" : "'.to_b.to_c'") + " is null. " + + "Can not read field 'to_d'."); } a.to_b.to_c = new C(); try { @@ -182,59 +739,8 @@ Asserts.fail(); } catch (NullPointerException e) { checkMessage("a.to_b.to_c.to_d.num = 99 // a.to_b.to_c.to_d is null", e.getMessage(), - "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"); - } - } - - public void testArrayChasing() { - int[][][][][] a = null; - try { - a[0][0][0][0][0] = 99; - Asserts.fail(); - } catch (NullPointerException e) { - checkMessage("int[0][0][0][0][0] = 99 // a is null", e.getMessage(), - "while trying to load from a null object array loaded from " + - (hasDebugInfo ? "local variable 'a'" : "a local variable at slot 1")); - } - a = new int[1][][][][]; - try { - a[0][0][0][0][0] = 99; - Asserts.fail(); - } catch (NullPointerException e) { - checkMessage("int[0][0][0][0][0] = 99 // a[0] is null", e.getMessage(), - "while trying to load from a null object array loaded from an array (which itself was loaded from " + - (hasDebugInfo ? "local variable 'a'" : "a local variable at slot 1") + - ") with an index loaded from a constant"); - } - a[0] = new int[1][][][]; - try { - a[0][0][0][0][0] = 99; - Asserts.fail(); - } catch (NullPointerException e) { - checkMessage("int[0][0][0][0][0] = 99 // a[0][0] is null", e.getMessage(), - "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"); - } - a[0][0] = new int[1][][]; - try { - a[0][0][0][0][0] = 99; - Asserts.fail(); - } catch (NullPointerException e) { - checkMessage("int[0][0][0][0][0] = 99 // a[0][0][0] is null", e.getMessage(), - "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"); - } - a[0][0][0] = new int[1][]; - try { - a[0][0][0][0][0] = 99; - Asserts.fail(); - } catch (NullPointerException e) { - checkMessage("int[0][0][0][0][0] = 99 // a[0][0][0][0] is null", 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 a constant"); - } - a[0][0][0][0] = new int[1]; - try { - a[0][0][0][0][0] = 99; - } catch (NullPointerException e) { - Asserts.fail(); + (hasDebugInfo ? "'a.to_b.to_c.to_d'" : "'.to_b.to_c.to_d'") + " is null. " + + "Can not write field 'num'."); } } @@ -245,8 +751,8 @@ Asserts.fail(); } catch (NullPointerException e) { checkMessage("a.getB().getBfromB().getC().getD().num = 99 // a is null", e.getMessage(), - "while trying to invoke the method 'NullPointerExceptionTest$A.getB()LNullPointerExceptionTest$B;' on a null reference loaded from " + - (hasDebugInfo ? "local variable 'a'" : "a local variable at slot 1")); + (hasDebugInfo ? "'a" : "'") + "' is null. " + + "Can not invoke method 'NullPointerExceptionTest$B NullPointerExceptionTest$A.getB()'."); } a = new A(); try { @@ -254,7 +760,8 @@ Asserts.fail(); } catch (NullPointerException e) { checkMessage("a.getB().getBfromB().getC().getD().num = 99 // a.getB() is null", e.getMessage(), - "while trying to invoke the method 'NullPointerExceptionTest$B.getBfromB()LNullPointerExceptionTest$B;' on a null reference returned from 'NullPointerExceptionTest$A.getB()LNullPointerExceptionTest$B;'"); + "The return value of 'NullPointerExceptionTest$B NullPointerExceptionTest$A.getB()' is null. " + + "Can not invoke method 'NullPointerExceptionTest$B NullPointerExceptionTest$B.getBfromB()'."); } a.to_b = new B(); try { @@ -262,7 +769,8 @@ Asserts.fail(); } catch (NullPointerException e) { checkMessage("a.getB().getBfromB().getC().getD().num = 99 // a.getB().getBfromB() is null", e.getMessage(), - "while trying to invoke the method 'NullPointerExceptionTest$B.getC()LNullPointerExceptionTest$C;' on a null reference returned from 'NullPointerExceptionTest$B.getBfromB()LNullPointerExceptionTest$B;'"); + "The return value of 'NullPointerExceptionTest$B NullPointerExceptionTest$B.getBfromB()' is null. " + + "Can not invoke method 'NullPointerExceptionTest$C NullPointerExceptionTest$B.getC()'."); } a.to_b.to_b = new B(); try { @@ -270,7 +778,8 @@ Asserts.fail(); } catch (NullPointerException e) { checkMessage("a.getB().getBfromB().getC().getD().num = 99 // a.getB().getBfromB().getC() is null", e.getMessage(), - "while trying to invoke the method 'NullPointerExceptionTest$C.getD()LNullPointerExceptionTest$D;' on a null reference returned from 'NullPointerExceptionTest$B.getC()LNullPointerExceptionTest$C;'"); + "The return value of 'NullPointerExceptionTest$C NullPointerExceptionTest$B.getC()' is null. " + + "Can not invoke method 'NullPointerExceptionTest$D NullPointerExceptionTest$C.getD()'."); } a.to_b.to_b.to_c = new C(); try { @@ -278,7 +787,8 @@ Asserts.fail(); } catch (NullPointerException e) { checkMessage("a.getB().getBfromB().getC().getD().num = 99 // a.getB().getBfromB().getC().getD() is null", e.getMessage(), - "while trying to write the field 'NullPointerExceptionTest$D.num' of a null object returned from 'NullPointerExceptionTest$C.getD()LNullPointerExceptionTest$D;'"); + "The return value of 'NullPointerExceptionTest$D NullPointerExceptionTest$C.getD()' is null. " + + "Can not write field 'num'."); } } @@ -289,8 +799,8 @@ Asserts.fail(); } catch (NullPointerException e) { checkMessage("a.getB().getBfromB().to_c.to_d.ar[0][0] = 99; // a is null", e.getMessage(), - "while trying to invoke the method 'NullPointerExceptionTest$A.getB()LNullPointerExceptionTest$B;' on a null reference loaded from " + - (hasDebugInfo ? "local variable 'a'" : "a local variable at slot 1")); + (hasDebugInfo ? "'a'" : "''") + " is null. " + + "Can not invoke method 'NullPointerExceptionTest$B NullPointerExceptionTest$A.getB()'."); } a = new A(); try { @@ -298,7 +808,8 @@ Asserts.fail(); } catch (NullPointerException e) { checkMessage("a.getB().getBfromB().to_c.to_d.ar[0][0] = 99; // a.getB() is null", e.getMessage(), - "while trying to invoke the method 'NullPointerExceptionTest$B.getBfromB()LNullPointerExceptionTest$B;' on a null reference returned from 'NullPointerExceptionTest$A.getB()LNullPointerExceptionTest$B;'"); + "The return value of 'NullPointerExceptionTest$B NullPointerExceptionTest$A.getB()' is null. " + + "Can not invoke method 'NullPointerExceptionTest$B NullPointerExceptionTest$B.getBfromB()'."); } a.to_b = new B(); try { @@ -306,7 +817,8 @@ Asserts.fail(); } catch (NullPointerException e) { checkMessage("a.getB().getBfromB().to_c.to_d.ar[0][0] = 99; // a.getB().getBfromB() is null", e.getMessage(), - "while trying to read the field 'to_c' of a null object returned from 'NullPointerExceptionTest$B.getBfromB()LNullPointerExceptionTest$B;'"); + "The return value of 'NullPointerExceptionTest$B NullPointerExceptionTest$B.getBfromB()' is null. " + + "Can not read field 'to_c'."); } a.to_b.to_b = new B(); try { @@ -314,7 +826,8 @@ Asserts.fail(); } catch (NullPointerException e) { checkMessage("a.getB().getBfromB().to_c.to_d.ar[0][0] = 99; // a.getB().getBfromB().to_c is null", e.getMessage(), - "while trying to read the field 'to_d' of a null object loaded from field 'NullPointerExceptionTest$B.to_c' of an object returned from 'NullPointerExceptionTest$B.getBfromB()LNullPointerExceptionTest$B;'"); + "'NullPointerExceptionTest$B NullPointerExceptionTest$B.getBfromB().to_c' is null. " + + "Can not read field 'to_d'."); } a.to_b.to_b.to_c = new C(); try { @@ -322,7 +835,8 @@ Asserts.fail(); } catch (NullPointerException e) { checkMessage("a.getB().getBfromB().to_c.to_d.ar[0][0] = 99; // a.getB().getBfromB().to_c.to_d is null", e.getMessage(), - "while trying to read the field 'ar' of a null object loaded from field 'NullPointerExceptionTest$C.to_d' of an object loaded from field 'NullPointerExceptionTest$B.to_c' of an object"); + "'NullPointerExceptionTest$B NullPointerExceptionTest$B.getBfromB().to_c.to_d' is null. " + + "Can not read field 'ar'."); } a.to_b.to_b.to_c.to_d = new D(); try { @@ -330,14 +844,16 @@ Asserts.fail(); } catch (NullPointerException e) { checkMessage("a.getB().getBfromB().to_c.to_d.ar[0][0] = 99; // a.getB().getBfromB().to_c.to_d.ar is null", e.getMessage(), - "while trying to load from a null object array loaded from field 'NullPointerExceptionTest$D.ar' of an object loaded from field 'NullPointerExceptionTest$C.to_d' of an object"); + "'NullPointerExceptionTest$B NullPointerExceptionTest$B.getBfromB().to_c.to_d.ar' is null. " + + "Can not load from null object array."); } try { a.getB().getBfromB().getC().getD().ar[0][0] = 99; Asserts.fail(); } catch (NullPointerException e) { checkMessage("a.getB().getBfromB().getC().getD().ar[0][0] = 99; // a.getB().getBfromB().getC().getD().ar is null", e.getMessage(), - "while trying to load from a null object array loaded from field 'NullPointerExceptionTest$D.ar' of an object returned from 'NullPointerExceptionTest$C.getD()LNullPointerExceptionTest$D;'"); + "'NullPointerExceptionTest$D NullPointerExceptionTest$C.getD().ar' is null. " + + "Can not load from null object array."); } a.to_b.to_b.to_c.to_d.ar = new int[1][]; try { @@ -345,25 +861,255 @@ Asserts.fail(); } catch (NullPointerException e) { checkMessage("a.getB().getBfromB().to_c.to_d.ar[0][0] = 99; // a.getB().getBfromB().to_c.to_d.ar[0] is null", e.getMessage(), - "while trying to store to a null int array loaded from an array (which itself was loaded from field 'NullPointerExceptionTest$D.ar' of an object) with an index loaded from a constant"); + "'NullPointerExceptionTest$B NullPointerExceptionTest$B.getBfromB().to_c.to_d.ar[0]' is null. " + + "Can not store to null int array."); } try { a.getB().getBfromB().getC().getD().ar[0][0] = 99; Asserts.fail(); } catch (NullPointerException e) { checkMessage("a.getB().getBfromB().getC().getD().ar[0][0] = 99; // a.getB().getBfromB().getC().getD().ar[0] is null", e.getMessage(), - "while trying to store to a null int array loaded from an array (which itself was loaded from field 'NullPointerExceptionTest$D.ar' of an object) with an index loaded from a constant"); + "'NullPointerExceptionTest$D NullPointerExceptionTest$C.getD().ar[0]' is null. " + + "Can not store to null int array."); + } + } + + // Helper method to cause test case. + private Object returnNull(String[][] dummy1, int[][][] dummy2, float dummy3) { + return null; + } + + // Helper method to cause test case. + private NullPointerExceptionTest returnMeAsNull(Throwable dummy1, int dummy2, char dummy3) { + return null; + } + + // Helper interface for test cases. + static interface DoubleArrayGen { + public double[] getArray(); + } + + // Helper class for test cases. + static class DoubleArrayGenImpl implements DoubleArrayGen { + @Override + public double[] getArray() { + return null; + } + } + + // Helper class for test cases. + static class NullPointerGenerator { + public static Object nullReturner(boolean dummy1) { + return null; + } + + public Object returnMyNull(double dummy1, long dummy2, short dummy3) { + return null; + } + } + + // Helper method to cause test case. + public void ImplTestLoadedFromMethod(DoubleArrayGen gen) { + try { + (gen.getArray())[0] = 1.0; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("(gen.getArray())[0]", e.getMessage(), + "The return value of 'double[] NullPointerExceptionTest$DoubleArrayGen.getArray()' is null. Can not store to null double array."); } } + public void testNullEntity() { + int[][] a = new int[820][]; + + test_iload(); + test_lload(); + test_fload(); + // test_dload(); + test_aload(); + // aload_0: 'this' + try { + this.nullInstanceField.nullInstanceField = null; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("this.nullInstanceField.nullInstanceField = null", e.getMessage(), + "'this.nullInstanceField' is null. Can not write field 'nullInstanceField'."); + } + + // aconst_null + try { + throw null; + } catch (NullPointerException e) { + checkMessage("throw null", e.getMessage(), + "'null' is null. Can not throw a null exception object."); + } + // iconst_0 + try { + a[0][0] = 77; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("a[0][0]", e.getMessage(), + (hasDebugInfo ? "'a[0]'" : "'[0]'") + " is null. " + + "Can not store to null int array."); + } + // iconst_1 + try { + a[1][0] = 77; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("a[1][0]", e.getMessage(), + (hasDebugInfo ? "'a[1]'" : "'[1]'") + " is null. " + + "Can not store to null int array."); + } + // iconst_2 + try { + a[2][0] = 77; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("a[2][0]", e.getMessage(), + (hasDebugInfo ? "'a[2]'" : "'[2]'") + " is null. " + + "Can not store to null int array."); + } + // iconst_3 + try { + a[3][0] = 77; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("a[3][0]", e.getMessage(), + (hasDebugInfo ? "'a[3]'" : "'[3]'") + " is null. " + + "Can not store to null int array."); + } + // iconst_4 + try { + a[4][0] = 77; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("a[4][0]", e.getMessage(), + (hasDebugInfo ? "'a[4]'" : "'[4]'") + " is null. " + + "Can not store to null int array."); + } + // iconst_5 + try { + a[5][0] = 77; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("a[5][0]", e.getMessage(), + (hasDebugInfo ? "'a[5]'" : "'[5]'") + " is null. " + + "Can not store to null int array."); + } + // long --> iconst + try { + a[(int)0L][0] = 77; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("a[(int)0L][0]", e.getMessage(), + (hasDebugInfo ? "'a[0]'" : "'[0]'") + " is null. " + + "Can not store to null int array."); + } + // bipush + try { + a[139 /*0x77*/][0] = 77; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("a[139][0]", e.getMessage(), + (hasDebugInfo ? "'a[139]'" : "'[139]'") + " is null. " + + "Can not store to null int array."); + } + // sipush + try { + a[819 /*0x333*/][0] = 77; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("a[819][0]", e.getMessage(), + (hasDebugInfo ? "'a[819]'" : "'[819]'") + " is null. " + + "Can not store to null int array."); + } + + // aaload, with recursive descend. + testArrayChasing(); + + // getstatic + try { + Asserts.assertTrue(((float[]) nullStaticField)[0] == 1.0f); + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("((float[]) nullStaticField)[0]", e.getMessage(), + "'static NullPointerExceptionTest.nullStaticField' is null. Can not load from null float array."); + } + + // getfield, with recursive descend. + testPointerChasing(); + + // invokestatic + try { + Asserts.assertTrue(((char[]) NullPointerGenerator.nullReturner(false))[0] == 'A'); + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("((char[]) NullPointerGenerator.nullReturner(false))[0]", e.getMessage(), + "The return value of 'java.lang.Object NullPointerExceptionTest$NullPointerGenerator.nullReturner(boolean)' is null. Can not load from null char array."); + } + // invokevirtual + try { + Asserts.assertTrue(((char[]) (new NullPointerGenerator().returnMyNull(1, 1, (short) 1)))[0] == 'a'); + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("((char[]) (new NullPointerGenerator().returnMyNull(1, 1, (short) 1)))[0]", e.getMessage(), + "The return value of 'java.lang.Object NullPointerExceptionTest$NullPointerGenerator.returnMyNull(double, long, short)' is null. Can not load from null char array."); + } + // Call with array arguments. + try { + Asserts.assertTrue(((double[]) returnNull(null, null, 1f))[0] == 1.0); + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("((double[]) returnNull(null, null, 1f))[0] ", e.getMessage(), + "The return value of 'java.lang.Object NullPointerExceptionTest.returnNull(java.lang.String[][], int[][][], float)' is null. Can not load from null double array."); + } + // invokeinterface + ImplTestLoadedFromMethod(new DoubleArrayGenImpl()); + try { + returnMeAsNull(null, 1, 'A').dag = null; + Asserts.fail(); + } catch (NullPointerException e) { + checkMessage("returnMeAsNull(null, 1, 'A').dag = null", e.getMessage(), + "The return value of 'NullPointerExceptionTest NullPointerExceptionTest.returnMeAsNull(java.lang.Throwable, int, char)' is null. Can not write field 'dag'."); + } + testMethodChasing(); + + // Mixed recursive descend. + testMixedChasing(); + + } + + + public void testCreation() throws Exception { + // If allocated with new, the message should not be generated. + Asserts.assertNull(new NullPointerException().getMessage()); + String msg = new String("A pointless message."); + Asserts.assertTrue(new NullPointerException(msg).getMessage() == msg); + + // If created via reflection, the message should not be generated. + Exception ex = NullPointerException.class.getDeclaredConstructor().newInstance(); + Asserts.assertNull(ex.getMessage()); + } + + public void testNative() throws Exception { + // If NPE is thrown in a native method, the message should + // not be generated. + try { + Class.forName(null); + Asserts.fail(); + } catch (NullPointerException e) { + Asserts.assertNull(e.getMessage()); + } + + } // Test we get the same message calling npe.getMessage() twice. public void testSameMessage() throws Exception { Object null_o = null; String expectedMsg = - "while trying to invoke the method 'java.lang.Object.hashCode()I'" + - " on a null reference loaded from " + - (hasDebugInfo ? "local variable 'null_o'" : "a local variable at slot 1"); + (hasDebugInfo ? "'null_o" : "'") + "' is null. " + + "Can not invoke method 'int java.lang.Object.hashCode()'."; try { null_o.hashCode(); @@ -374,30 +1120,13 @@ String msg2 = npe.getMessage(); Asserts.assertTrue(msg1.equals(msg2)); // It was decided that getMessage should generate the - // message anew on every call, so this does not hold any more. + // message anew on every call, so this does not hold. + //Asserts.assertTrue(msg1 == msg2); Asserts.assertFalse(msg1 == msg2); } } - /** - * - */ - public void testCreationViaNew() { - Asserts.assertNull(new NullPointerException().getMessage()); - } - - /** - * @throws Exception - */ - public void testCreationViaReflection() throws Exception { - Exception ex = NullPointerException.class.getDeclaredConstructor().newInstance(); - Asserts.assertNull(ex.getMessage()); - } - - /** - * @throws Exception - */ - public void testCreationViaSerialization() throws Exception { + public void testSerialization() throws Exception { // NPE without message. Object o1 = new NullPointerException(); ByteArrayOutputStream bos1 = new ByteArrayOutputStream(); @@ -429,9 +1158,9 @@ } catch (NullPointerException npe3) { o3 = npe3; msg3 = npe3.getMessage(); - checkMessage("null_o3.hashCode()", msg3, "while trying to invoke the method 'java.lang.Object.hashCode()I'" + - " on a null reference loaded from " + - (hasDebugInfo ? "local variable 'null_o3'" : "a local variable at slot 14")); + checkMessage("null_o3.hashCode()", msg3, + (hasDebugInfo ? "'null_o3'" : "''") + " is null. " + + "Can not invoke method 'int java.lang.Object.hashCode()'."); } ByteArrayOutputStream bos3 = new ByteArrayOutputStream(); ObjectOutputStream oos3 = new ObjectOutputStream(bos3); @@ -446,791 +1175,124 @@ Asserts.assertEquals(ex3.getMessage(), null); } - /** - * - */ - @SuppressWarnings("null") - public void testLoadedFromLocalVariable1() { - Object o = null; - - try { - o.hashCode(); - Asserts.fail(); - } catch (NullPointerException e) { - 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")); - } - } - - /** - * - */ - @SuppressWarnings("null") - public void testLoadedFromLocalVariable2() { - Exception[] myVariable = null; - - try { - Asserts.assertNull(myVariable[0]); - Asserts.fail(); - } catch (NullPointerException e) { - 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")); - } - } - - /** - * - */ - @SuppressWarnings("null") - public void testLoadedFromLocalVariable3() { - Exception[] myVariable = null; - - try { - myVariable[0] = null; - Asserts.fail(); - } catch (NullPointerException e) { - 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")); - } - } - - /** - * - */ - @SuppressWarnings("null") - public void testLoadedFromLocalVariable4() { - Exception[] myVariable\u0096 = null; - - try { - Asserts.assertTrue(myVariable\u0096.length == 0); - Asserts.fail(); - } catch (NullPointerException e) { - 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")); - } - } - - /** - * @throws Exception - */ - @SuppressWarnings("null") - public void testLoadedFromLocalVariable5() throws Exception { - Exception myException = null; - - try { - throw myException; - } catch (NullPointerException e) { - 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")); - } - } - - /** - * - */ - @SuppressWarnings("null") - public void testLoadedFromLocalVariable6() { - byte[] myVariable = null; - int my_index = 1; - - try { - Asserts.assertTrue(myVariable[my_index] == 0); - Asserts.fail(); - } catch (NullPointerException e) { - 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")); - } - } - - /** - * - */ - @SuppressWarnings("null") - public void testLoadedFromLocalVariable7() { - byte[] myVariable = null; - - try { - myVariable[System.out.hashCode()] = (byte) 0; - Asserts.fail(); - } catch (NullPointerException e) { - 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")); - } - } - - /** - * - */ - public void testLoadedFromMethod1() { - try { - Asserts.assertTrue(((char[]) NullPointerGenerator.nullReturner(false))[0] == 'A'); - Asserts.fail(); - } catch (NullPointerException e) { - 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;'"); - } - } - - /** - * - */ - public void testLoadedFromMethod2() { - try { - Asserts.assertTrue(((char[]) (new NullPointerGenerator().returnMyNull(1, 1, (short) 1)))[0] == 'a'); - Asserts.fail(); - } catch (NullPointerException e) { - 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;'"); - } - } - - /** - * - */ - public void testLoadedFromMethod3() { - try { - Asserts.assertTrue(((double[]) returnNull(null, null, 1f))[0] == 1.0); - Asserts.fail(); - } catch (NullPointerException e) { - 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;'"); - } - } - - /** - * - */ - public void testLoadedFromMethod4() { - ImplTestLoadedFromMethod4(new DoubleArrayGenImpl()); - } - - /** - * @param gen - */ - public void ImplTestLoadedFromMethod4(DoubleArrayGen gen) { - try { - (gen.getArray())[0] = 1.0; - Asserts.fail(); - } catch (NullPointerException e) { - checkMessage("(gen.getArray())[0]", e.getMessage(), "while trying to store to a null double array returned from 'NullPointerExceptionTest$DoubleArrayGen.getArray()[D'"); - } - } - - /** - * - */ - public void testLoadedFromMethod5() { - try { - returnMeAsNull(null, 1, 'A').dag = null; - Asserts.fail(); - } catch (NullPointerException e) { - 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;'"); - } - /* - try { - returnMeAsNull(null, 1, 'A').dag.dag = null; - Asserts.fail(); - } catch (NullPointerException e) { - 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;'"); - } - */ - } - - /** - * - */ - @SuppressWarnings("null") - public void testLoadedFromMethod6() { - short[] sa = null; - - try { - Asserts.assertTrue(sa[0] == (short) 1); - Asserts.fail(); - } catch (NullPointerException e) { - 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")); - } - } - - /** - * - */ - @SuppressWarnings("null") - public void testLoadedFromMethod7() { - short[] sa = null; - - try { - sa[0] = 1; - Asserts.fail(); - } catch (NullPointerException e) { - 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")); - } - } - - /** - * - */ - public void testLoadedFromStaticField1() { - try { - Asserts.assertTrue(((float[]) nullStaticField)[0] == 1.0f); - Asserts.fail(); - } catch (NullPointerException e) { - checkMessage("((float[]) nullStaticField)[0]", e.getMessage(), "while trying to load from a null float array loaded from static field 'NullPointerExceptionTest.nullStaticField'"); - } - } - - /** - * - */ - public void testLoadedFromStaticField2() { - try { - ((float[]) nullStaticField)[0] = 1.0f; - Asserts.fail(); - } catch (NullPointerException e) { - checkMessage("((float[]) nullStaticField)[0] = 1.0f", e.getMessage(), "while trying to store to a null float array loaded from static field 'NullPointerExceptionTest.nullStaticField'"); - } - } - - /** - * - */ - public void testLoadedFromStaticField3() { - try { - Asserts.assertTrue(staticArray[0][0][0][0] == 1); - Asserts.fail(); - } catch (NullPointerException e) { - 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"); - } - } - - /** - * - */ - public void testLoadedFromStaticField4(int myIdx, int pos) { - try { - staticArray[0][0][pos][myIdx] = 2; - Asserts.fail(); - } catch (NullPointerException e) { - 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")); - } - } - - /** - * - */ - public void testLoadedFromStaticField5() { - try { - Asserts.assertTrue(staticLongArray[0][0] == 1L); - } catch (NullPointerException e) { - 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"); - } - } - - /** - * Test bipush for index. - */ - public void testLoadedFromStaticField5a() { - try { - Asserts.assertTrue(staticLongArray[139 /*0x77*/][0] == 1L); - } catch (NullPointerException e) { - 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"); - } - } - - /** - * Test sipush for index. - */ - public void testLoadedFromStaticField5b() { - try { - Asserts.assertTrue(staticLongArray[819 /*0x333*/][0] == 1L); - } catch (NullPointerException e) { - 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"); - } - } - - /** - * - */ - public void testLoadedFromStaticField6() { + public void testComplexMessages() { try { staticLongArray[0][0] = 2L; Asserts.fail(); } catch (NullPointerException e) { - 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"); + checkMessage("staticLongArray[0][0] = 2L", e.getMessage(), + "'static NullPointerExceptionTest.staticLongArray[0]' is null. " + + "Can not store to null long array."); } - } - /** - * - */ - public void testLoadedFromInstanceField1() { try { Asserts.assertTrue(this.nullInstanceField.nullInstanceField == null); Asserts.fail(); } catch (NullPointerException e) { - 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'"); + checkMessage("this.nullInstanceField.nullInstanceField", e.getMessage(), + "'this.nullInstanceField' is null. " + + "Can not read field 'nullInstanceField'."); } - } - - /** - * - */ - public void testLoadedFromInstanceField2() { - try { - this.nullInstanceField.nullInstanceField = null; - Asserts.fail(); - } catch (NullPointerException e) { - 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'"); - } - } - - /** - * - */ - public void testLoadedFromInstanceField3() { - NullPointerExceptionTest obj = this; try { + NullPointerExceptionTest obj = this; Asserts.assertNull(obj.dag.getArray().clone()); Asserts.fail(); } catch (NullPointerException e) { - 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")); + checkMessage("obj.dag.getArray().clone()", e.getMessage(), + (hasDebugInfo ? "'obj" : "'") + ".dag' is null. " + + "Can not invoke method 'double[] NullPointerExceptionTest$DoubleArrayGen.getArray()'."); } - } - - /** - * - */ - public void testLoadedFromInstanceField4() { - int indexes[] = new int[1]; - - NullPointerExceptionTest[] objs = new NullPointerExceptionTest[] {this}; - try { + int indexes[] = new int[1]; + NullPointerExceptionTest[] objs = new NullPointerExceptionTest[] {this}; Asserts.assertNull(objs[indexes[0]].nullInstanceField.returnNull(null, null, 1f)); Asserts.fail(); } catch (NullPointerException e) { - 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"); + checkMessage("objs[indexes[0]].nullInstanceField.returnNull(null, null, 1f)", e.getMessage(), + (hasDebugInfo ? "'objs[indexes" : "'[") + "[0]].nullInstanceField' is null. " + + "Can not invoke method 'java.lang.Object NullPointerExceptionTest.returnNull(java.lang.String[][], int[][][], float)'."); } - } - - /** - * - */ - public void testLoadedFromInstanceField5() { - int indexes[] = new int[1]; - - NullPointerExceptionTest[] objs = new NullPointerExceptionTest[] {this}; try { - Asserts.assertNull(objs[indexes[0]].nullInstanceField.toString().toCharArray().clone()); - } catch (NullPointerException e) { - 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"); - } - } - - /** - * - */ - public void testLoadedFromInstanceField6() { - int indexes[] = new int[1]; - - NullPointerExceptionTest[][] objs = - new NullPointerExceptionTest[][] {new NullPointerExceptionTest[] {this}}; - - try { - // Check monitorenter only, since we cannot probe monitorexit from Java. + int indexes[] = new int[1]; + NullPointerExceptionTest[][] objs = + new NullPointerExceptionTest[][] {new NullPointerExceptionTest[] {this}}; synchronized (objs[indexes[0]][0].nullInstanceField) { Asserts.fail(); } } catch (NullPointerException e) { - 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"); - } - } - - /** - * @throws ClassNotFoundException - */ - public void testInNative() throws ClassNotFoundException { - try { - Class.forName(null); - Asserts.fail(); - } catch (NullPointerException e) { - Asserts.assertNull(e.getMessage()); - } - } - - private Object returnNull(String[][] dummy1, int[][][] dummy2, float dummy3) { - return null; - } - - private NullPointerExceptionTest returnMeAsNull(Throwable dummy1, int dummy2, char dummy3){ - return null; - } - - static interface DoubleArrayGen { - public double[] getArray(); - } - - static class DoubleArrayGenImpl implements DoubleArrayGen { - @Override - public double[] getArray() { - return null; - } - } - - static class NullPointerGenerator { - public static Object nullReturner(boolean dummy1) { - return null; - } - - public Object returnMyNull(double dummy1, long dummy2, short dummy3) { - return null; - } - } - - /** - * - */ - public void testMissingLocalVariableTable() { - doTestMissingLocalVariableTable(names); - - String[] expectedHasDebugInfoGoodNames = new String[] { - "while trying to invoke the method 'java.lang.Object.hashCode()I' on a null reference " + - "loaded from field 'NullPointerExceptionTest.nullInstanceField' " + - "of an object loaded from 'this'", - "while trying to invoke the method 'java.lang.Object.hashCode()I' on a null reference loaded from " + - "local variable 'a1'", - "while trying to invoke the method 'java.lang.Object.hashCode()I' on a null reference loaded from " + - "local variable 'o1'", - "while trying to invoke the method 'java.lang.Object.hashCode()I' on a null reference loaded from " + - "local variable 'aa1'" - }; - - String[] expectedNoDebugInfoGoodNames = new String[] { - "while trying to invoke the method 'java.lang.Object.hashCode()I' on a null reference " + - "loaded from field 'NullPointerExceptionTest.nullInstanceField' " + - "of an object loaded from 'this'", - "while trying to invoke the method 'java.lang.Object.hashCode()I' on a null reference loaded from " + - "the parameter nr. 5 of the method", - "while trying to invoke the method 'java.lang.Object.hashCode()I' on a null reference loaded from " + - "the parameter nr. 2 of the method", - "while trying to invoke the method 'java.lang.Object.hashCode()I' on a null reference loaded from " + - "the parameter nr. 9 of the method" - }; - - String[] expectedNames; - if (hasDebugInfo) { - expectedNames = expectedHasDebugInfoGoodNames; - } else { - expectedNames = expectedNoDebugInfoGoodNames; - } - - // The two lists of messages should have the same length. - Asserts.assertEquals(names.size(), expectedNames.length); - - for (int i = 0; i < expectedNames.length; ++i) { - // GLGLGL not for now Asserts.assertEquals(names.get(i), expectedNames[i]); - } - } - - private void doTestMissingLocalVariableTable(ArrayList names) { - curr = names; - doTestMissingLocalVariableTable1(); - doTestMissingLocalVariableTable2(-1, null, false, 0.0, null, 0.1f, (byte) 0, (short) 0, null); - } - - private void doTestMissingLocalVariableTable1() { - try { - this.nullInstanceField.hashCode(); - Asserts.fail(); - } catch (NullPointerException e) { - curr.add(e.getMessage()); - } - } - - private void doTestMissingLocalVariableTable2(long l1, Object o1, boolean z1, double d1, Object[] a1, - float f1, byte b1, short s1, Object[][] aa1) { - try { - a1.hashCode(); - Asserts.fail(); - } - catch (NullPointerException e) { - curr.add(e.getMessage()); - } - - try { - o1.hashCode(); - Asserts.fail(); - } - catch (NullPointerException e) { - curr.add(e.getMessage()); - } - - try { - aa1.hashCode(); - Asserts.fail(); - } - catch (NullPointerException e) { - curr.add(e.getMessage()); + checkMessage("synchronized (objs[indexes[0]][0].nullInstanceField)", e.getMessage(), + (hasDebugInfo ? "'objs[indexes" : "'[" ) + "[0]][0].nullInstanceField' is null. " + + "Can not enter a null monitor."); } } - /** - * - */ - @SuppressWarnings("null") - public void testNullMessages() { - boolean[] za1 = null; - byte[] ba1 = null; - short[] sa1 = null; - char[] ca1 = null; - int[] ia1 = null; - long[] la1 = null; - float[] fa1 = null; - double[] da1 = null; - Object[] oa1 = null; - - Object[][] oa2 = new Object[2][]; - oa2[1] = oa1; - - try { - System.out.println(oa2[1][0]); - Asserts.fail(); - } catch (NullPointerException e) { - checkMessage("oa2[1][0]", e.getMessage(), - "while trying to load from a null object array loaded from an array " + - "(which itself was loaded from " + - (hasDebugInfo ? "local variable 'oa2'" : "a local variable at slot 10") + ") " + - "with an index loaded from a constant"); - } - - - try { - System.out.println(za1[0]); - Asserts.fail(); - } catch (NullPointerException e) { - checkMessage("za1[0]", e.getMessage(), - "while trying to load from a null byte (or boolean) array loaded from " + - (hasDebugInfo ? "local variable 'za1'" : "a local variable at slot 1")); - } - - try { - System.out.println(ba1[0]); - Asserts.fail(); - } catch (NullPointerException e) { - checkMessage("ba1[0]", e.getMessage(), - "while trying to load from a null byte (or boolean) array loaded from " + - (hasDebugInfo ? "local variable 'ba1'" : "a local variable at slot 2")); - } - - try { - System.out.println(sa1[0]); - Asserts.fail(); - } catch (NullPointerException e) { - checkMessage("sa1[0]", e.getMessage(), - "while trying to load from a null short array loaded from " + - (hasDebugInfo ? "local variable 'sa1'" : "a local variable at slot 3")); - } + // Generates: + // class E implements E0 { + // public int throwNPE(F f) { + // return f.i; + // } + // } + static byte[] generateTestClass() { + ClassWriter cw = new ClassWriter(0); + MethodVisitor mv; - try { - System.out.println(ca1[0]); - Asserts.fail(); - } catch (NullPointerException e) { - checkMessage("ca1[0]", e.getMessage(), - "while trying to load from a null char array loaded from " + - (hasDebugInfo ? "local variable 'ca1'" : "a local variable at slot 4")); - } - - try { - System.out.println(ia1[0]); - Asserts.fail(); - } catch (NullPointerException e) { - checkMessage("ia1[0]", e.getMessage(), - "while trying to load from a null int array loaded from " + - (hasDebugInfo ? "local variable 'ia1'" : "a local variable at slot 5")); - } - - try { - System.out.println(la1[0]); - Asserts.fail(); - } catch (NullPointerException e) { - checkMessage("la1[0]", e.getMessage(), - "while trying to load from a null long array loaded from " + - (hasDebugInfo ? "local variable 'la1'" : "a local variable at slot 6")); - } + cw.visit(57, ACC_SUPER, "E", null, "java/lang/Object", new String[] { "E0" }); - try { - System.out.println(fa1[0]); - Asserts.fail(); - } catch (NullPointerException e) { - checkMessage("fa1[0]", e.getMessage(), - "while trying to load from a null float array loaded from " + - (hasDebugInfo ? "local variable 'fa1'" : "a local variable at slot 7")); - } - - try { - System.out.println(da1[0]); - Asserts.fail(); - } catch (NullPointerException e) { - checkMessage("da1[0]", e.getMessage(), - "while trying to load from a null double array loaded from " + - (hasDebugInfo ? "local variable 'da1'" : "a local variable at slot 8")); - } - - try { - System.out.println(oa1[0]); - Asserts.fail(); - } catch (NullPointerException e) { - checkMessage("oa1[0]", e.getMessage(), - "while trying to load from a null object array loaded from " + - (hasDebugInfo ? "local variable 'oa1'" : "a local variable at slot 9")); - } - - try { - System.out.println(za1[0] = false); - Asserts.fail(); - } catch (NullPointerException e) { - checkMessage("za1[0] = false", e.getMessage(), - "while trying to store to a null byte (or boolean) array loaded from " + - (hasDebugInfo ? "local variable 'za1'" : "a local variable at slot 1")); - } - - try { - System.out.println(ba1[0] = 0); - Asserts.fail(); - } catch (NullPointerException e) { - checkMessage("ba1[0] = 0", e.getMessage(), - "while trying to store to a null byte (or boolean) array loaded from " + - (hasDebugInfo ? "local variable 'ba1'" : "a local variable at slot 2")); + { + mv = cw.visitMethod(0, "", "()V", null, null); + mv.visitCode(); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false); + mv.visitInsn(RETURN); + mv.visitMaxs(1, 1); + mv.visitEnd(); } - try { - System.out.println(sa1[0] = 0); - Asserts.fail(); - } catch (NullPointerException e) { - checkMessage("sa1[0] = 0", e.getMessage(), - "while trying to store to a null short array loaded from " + - (hasDebugInfo ? "local variable 'sa1'" : "a local variable at slot 3")); + { + mv = cw.visitMethod(ACC_PUBLIC, "throwNPE", "(LF;)I", null, null); + mv.visitCode(); + Label label0 = new Label(); + mv.visitLabel(label0); + mv.visitLineNumber(118, label0); + mv.visitVarInsn(ALOAD, 1); + mv.visitFieldInsn(GETFIELD, "F", "i", "I"); + mv.visitInsn(IRETURN); + Label label1 = new Label(); + mv.visitLabel(label1); + mv.visitLocalVariable("this", "LE;", null, label0, label1, 0); + mv.visitLocalVariable("f", "LE;", null, label0, label1, 1); + mv.visitMaxs(1, 2); + mv.visitEnd(); } - - try { - System.out.println(ca1[0] = 0); - Asserts.fail(); - } catch (NullPointerException e) { - checkMessage("ca1[0] = 0", e.getMessage(), - "while trying to store to a null char array loaded from " + - (hasDebugInfo ? "local variable 'ca1'" : "a local variable at slot 4")); - } - - try { - System.out.println(ia1[0] = 0); - Asserts.fail(); - } catch (NullPointerException e) { - checkMessage("ia1[0] = 0", e.getMessage(), - "while trying to store to a null int array loaded from " + - (hasDebugInfo ? "local variable 'ia1'" : "a local variable at slot 5")); - } + cw.visitEnd(); - try { - System.out.println(la1[0] = 0); - Asserts.fail(); - } catch (NullPointerException e) { - checkMessage("la1[0] = 0", e.getMessage(), - "while trying to store to a null long array loaded from " + - (hasDebugInfo ? "local variable 'la1'" : "a local variable at slot 6")); - } - - try { - System.out.println(fa1[0] = 0); - Asserts.fail(); - } catch (NullPointerException e) { - checkMessage("fa1[0] = 0", e.getMessage(), - "while trying to store to a null float array loaded from " + - (hasDebugInfo ? "local variable 'fa1'" : "a local variable at slot 7")); - } + return cw.toByteArray(); + } - try { - System.out.println(da1[0] = 0); - Asserts.fail(); - } catch (NullPointerException e) { - checkMessage("da1[0] = 0", e.getMessage(), - "while trying to store to a null double array loaded from " + - (hasDebugInfo ? "local variable 'da1'" : "a local variable at slot 8")); - } - - try { - System.out.println(oa1[0] = null); - Asserts.fail(); - } catch (NullPointerException e) { - checkMessage("oa1[0] = null", e.getMessage(), - "while trying to store to a null object array loaded from " + - (hasDebugInfo ? "local variable 'oa1'" : "a local variable at slot 9")); - } - + // Tests that a class generated on the fly is handled properly. + public void testGeneratedCode() throws Exception { + byte[] classBytes = generateTestClass(); + Lookup lookup = lookup(); + Class clazz = lookup.defineClass(classBytes); + E0 e = (E0) clazz.getDeclaredConstructor().newInstance(); try { - System.out.println(nullInstanceField.nullInstanceField); - Asserts.fail(); - } catch (NullPointerException e) { - checkMessage("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'"); - } - - try { - System.out.println(nullInstanceField.nullInstanceField = null); - Asserts.fail(); - } catch (NullPointerException e) { - checkMessage("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'"); - } - - try { - System.out.println(za1.length); - Asserts.fail(); - } catch (NullPointerException e) { - checkMessage("za1.length", e.getMessage(), - "while trying to get the length of a null array loaded from " + - (hasDebugInfo ? "local variable 'za1'" : "a local variable at slot 1")); - } - - try { - throw null; - } catch (NullPointerException e) { - checkMessage("throw null", e.getMessage(), - "while trying to throw a null exception object loaded " + - "from a constant"); - } - - try { - synchronized (nullInstanceField) { - // desired - } - } catch (NullPointerException e) { - checkMessage("synchronized (nullInstanceField)", e.getMessage(), - "while trying to enter a null monitor loaded from field " + - "'NullPointerExceptionTest.nullInstanceField' of an object loaded from " + - "'this'"); - } - - try { - nullInstanceField.testCreationViaNew(); - Asserts.fail(); - } catch (NullPointerException e) { - checkMessage("nullInstanceField.testCreationViaNew()", e.getMessage(), - "while trying to invoke the method 'NullPointerExceptionTest.testCreationViaNew()V' on a null reference " + - "loaded from field 'NullPointerExceptionTest.nullInstanceField' of an " + - "object loaded from 'this'"); - } - - try { - nullInstanceField.testNullMessages(); - Asserts.fail(); - } catch (NullPointerException e) { - checkMessage("nullInstanceField.testNullMessages()", e.getMessage(), - "while trying to invoke the method 'NullPointerExceptionTest.testNullMessages()V' on a null reference " + - "loaded from field 'NullPointerExceptionTest.nullInstanceField' of an " + - "object loaded from 'this'"); - } - - try { - // If we can get the value from more than one bci, we cannot know which one. - (Math.random() < 0.5 ? oa1 : (new Object[1])[0]).equals(""); - } catch (NullPointerException e) { - checkMessage("(Math.random() < 0.5 ? oa1 : (new Object[1])[0]).equals(\"\")", e.getMessage(), - "while trying to invoke the method 'java.lang.Object.equals(Ljava/lang/Object;)Z' on a null reference"); + e.throwNPE(null); + } catch (NullPointerException ex) { + checkMessage("return f.i;", + ex.getMessage(), + "'f' is null. Can not read field 'i'."); } } } + +// Helper interface for test cases needed for generateTestClass(). +interface E0 { + public int throwNPE(F f); +} + +// Helper class for test cases needed for generateTestClass(). +class F { + int i; +}