2323
2424/*
2525 * @test
26- * @summary Test the messages for 1-arg requireNonNull .
26+ * @summary Test the messages for arbitrary null-check APIs .
2727 * @bug 8233268
2828 * @library /test/lib
29- * @compile -g RequireNonNullTest.java
30- * @run junit/othervm -XX:+ShowCodeDetailsInExceptionMessages RequireNonNullTest
29+ * @modules java.base/jdk.internal.access
30+ * @compile -g NullCheckAPITest.java
31+ * @run junit/othervm -DnullCheckAPI.nestedThrow=true -XX:+ShowCodeDetailsInExceptionMessages NullCheckAPITest
32+ * @run junit/othervm -DnullCheckAPI.nestedThrow=false -XX:+ShowCodeDetailsInExceptionMessages NullCheckAPITest
3133 */
3234
3335import java .lang .reflect .InvocationTargetException ;
3436import java .lang .reflect .ParameterizedType ;
35- import java .util .Objects ;
3637
38+ import jdk .internal .access .JavaLangAccess ;
39+ import jdk .internal .access .SharedSecrets ;
40+ import org .junit .jupiter .api .Disabled ;
3741import org .junit .jupiter .api .Test ;
3842import org .junit .jupiter .api .function .Executable ;
3943
4044import static org .junit .jupiter .api .Assertions .assertEquals ;
4145import static org .junit .jupiter .api .Assertions .assertThrows ;
4246
43- public class RequireNonNullTest {
47+ public class NullCheckAPITest {
48+
49+ private static final JavaLangAccess JLA = SharedSecrets .getJavaLangAccess ();
50+ private static final boolean NESTED_THROW = Boolean .getBoolean ("nullCheckAPI.nestedThrow" );
51+
52+ // An arbitrary null-checking API
53+ static void nullCheck (Object arg ) {
54+ if (arg == null ) {
55+ if (NESTED_THROW ) {
56+ // 2 offset: nullCheck, throwNpe;
57+ throwNpe ();
58+ } else {
59+ // 1 offset: nullCheck
60+ throw JLA .extendedNullPointerException (1 , 0 );
61+ }
62+ }
63+ }
64+
65+ static void throwNpe () {
66+ throw JLA .extendedNullPointerException (2 , 0 );
67+ }
4468
4569 /// A simple NPE message for an expression
4670 static String simpleMessage (String cause ) {
@@ -64,32 +88,38 @@ static void checkInvocationMessage(Executable action, String cause) {
6488
6589 class Dummy { Object field ; }
6690
91+ @ Test
92+ void test () {
93+ checkSimpleMessage (() -> generateVariableNpe (null ), "myA" );
94+ checkSimpleMessage (() -> generateVariableNpe (new Dummy ()), "myA.field" );
95+
96+ checkInvocationMessage (() -> nullCheck (int .class .getSuperclass ()), "java.lang.Class.getSuperclass()" );
97+ }
98+
6799 static class One extends Dummy {
68- One (RequireNonNullTest rnnt ) {
100+ One (NullCheckAPITest rnnt ) {
69101 rnnt .super ();
70102 }
71103 }
72104
73105 @ Test
74- void test () {
75- checkSimpleMessage (() -> generateVariableNpe (null ), "myA" );
76- checkSimpleMessage (() -> generateVariableNpe (new Dummy ()), "myA.field" );
106+ @ Disabled ("Requires javac's API support" )
107+ void testRequireNonNull () {
77108 checkSimpleMessage (() -> {
78- RequireNonNullTest t = null ;
109+ NullCheckAPITest t = null ;
79110 t .new Dummy ();
80111 }, "t" );
81112 checkSimpleMessage (() -> new One (null ), "rnnt" );
82113
83114 var npe = assertThrows (NullPointerException .class , () -> {
84115 try {
85- Dummy .class .getDeclaredConstructor (RequireNonNullTest .class ).newInstance ((Object ) null );
116+ Dummy .class .getDeclaredConstructor (NullCheckAPITest .class ).newInstance ((Object ) null );
86117 } catch (InvocationTargetException ex ) {
87118 throw ex .getCause ();
88119 }
89120 });
90121 assertEquals ("\" this$0\" is null" , npe .getMessage ());
91122
92- checkInvocationMessage (() -> Objects .requireNonNull (int .class .getSuperclass ()), "java.lang.Class.getSuperclass()" );
93123 checkInvocationMessage (() -> {
94124 switch (int .class .getGenericSuperclass ()) {
95125 case ParameterizedType pt -> {}
@@ -101,7 +131,7 @@ void test() {
101131
102132 // A method that generate NPE from variables
103133 static void generateVariableNpe (Dummy myA ) {
104- Objects . requireNonNull (myA );
105- Objects . requireNonNull (myA .field );
134+ nullCheck (myA );
135+ nullCheck (myA .field );
106136 }
107137}
0 commit comments