test/jdk/java/lang/invoke/MethodHandlesGeneralTest.java
changeset 54445 a5da0277d9bb
parent 54295 49c4b23d8d0a
--- a/test/jdk/java/lang/invoke/MethodHandlesGeneralTest.java	Fri Apr 05 15:57:33 2019 -0700
+++ b/test/jdk/java/lang/invoke/MethodHandlesGeneralTest.java	Sat Apr 06 21:05:58 2019 +0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -635,7 +635,7 @@
 
     public void testGetter(int testMode) throws Throwable {
         Lookup lookup = PRIVATE;  // FIXME: test more lookups than this one
-        for (Object[] c : HasFields.CASES) {
+        for (Object[] c : HasFields.testCasesFor(testMode)) {
             boolean positive = (c[1] != Error.class);
             testGetter(positive, lookup, c[0], c[1], testMode);
             if (positive)
@@ -665,7 +665,6 @@
         boolean testNPE  = ((testMode0 & TEST_NPE) != 0);
         int testMode = testMode0 & ~(TEST_SETTER | TEST_BOUND | TEST_NPE);
         boolean positive = positive0 && !testNPE;
-        boolean isFinal;
         boolean isStatic;
         Class<?> fclass;
         String   fname;
@@ -673,14 +672,12 @@
         Field f = (fieldRef instanceof Field ? (Field)fieldRef : null);
         if (f != null) {
             isStatic = Modifier.isStatic(f.getModifiers());
-            isFinal  = Modifier.isFinal(f.getModifiers());
             fclass   = f.getDeclaringClass();
             fname    = f.getName();
             ftype    = f.getType();
         } else {
             Object[] scnt = (Object[]) fieldRef;
             isStatic = (Boolean)  scnt[0];
-            isFinal  = false;
             fclass   = (Class<?>) scnt[1];
             fname    = (String)   scnt[2];
             ftype    = (Class<?>) scnt[3];
@@ -724,19 +721,21 @@
                 ?   NoSuchFieldException.class
                 :   IllegalAccessException.class,
                 noAccess);
-            if (((testMode0 & TEST_SETTER) != 0) && (isFinal && isStatic)) return; // Final static field setter test failed as intended.
             if (verbosity >= 5)  ex.printStackTrace(System.out);
         }
         if (verbosity >= 3)
-            System.out.println((((testMode0 & TEST_UNREFLECT) != 0)?"unreflect":"find")
-                              +(((testMode0 & TEST_FIND_STATIC) != 0)?"Static":"")
-                              +(isGetter?"Getter":"Setter")
-                              +" "+fclass.getName()+"."+fname+"/"+ftype
-                              +" => "+mh
-                              +(noAccess == null ? "" : " !! "+noAccess));
+            System.out.format("%s%s %s.%s/%s => %s %s%n",
+                              (testMode0 & TEST_UNREFLECT) != 0
+                                  ? "unreflect"
+                                  : "find" + ((testMode0 & TEST_FIND_STATIC) != 0 ? "Static" : ""),
+                              (isGetter ? "Getter" : "Setter"),
+                              fclass.getName(), fname, ftype, mh,
+                              (noAccess == null ? "" : " !! "+noAccess));
+        // negative test case and expected noAccess, then done.
+        if (!positive && noAccess != null) return;
+        // positive test case but found noAccess, then error
         if (positive && !testNPE && noAccess != null)  throw new RuntimeException(noAccess);
         assertEquals(positive0 ? "positive test" : "negative test erroneously passed", positive0, mh != null);
-        assertFalse("Setter methods should throw an exception if passed a final static field.", ((testMode0 & TEST_SETTER) != 0) && (isFinal && isStatic));
         if (!positive && !testNPE)  return; // negative access test failed as expected
         assertEquals((isStatic ? 0 : 1)+(isGetter ? 0 : 1), mh.type().parameterCount());
         assertSame(mh.type(), expType);
@@ -762,6 +761,9 @@
             assertEquals(f.get(fields), value);  // clean to start with
         }
         Throwable caughtEx = null;
+        // non-final field and setAccessible(true) on instance field will have write access
+        boolean writeAccess = !Modifier.isFinal(f.getModifiers()) ||
+                              (!Modifier.isStatic(f.getModifiers()) && f.isAccessible());
         if (isGetter) {
             Object expValue = value;
             for (int i = 0; i <= 1; i++) {
@@ -785,7 +787,7 @@
                     }
                 }
                 assertEquals(sawValue, expValue);
-                if (f != null && f.getDeclaringClass() == HasFields.class && !isFinal) {
+                if (f != null && f.getDeclaringClass() == HasFields.class && writeAccess) {
                     Object random = randomArg(ftype);
                     f.set(fields, random);
                     expValue = random;
@@ -819,8 +821,8 @@
                 }
             }
         }
-        if ((f != null) && (f.getDeclaringClass() == HasFields.class) && !isFinal) {
-            f.set(fields, value);  // put it back if we changed it.
+        if (f != null && f.getDeclaringClass() == HasFields.class && writeAccess) {
+            f.set(fields, value);  // put it back if it has write access
         }
         if (testNPE) {
             if (caughtEx == null || !(caughtEx instanceof NullPointerException))
@@ -868,7 +870,8 @@
 
     public void testSetter(int testMode) throws Throwable {
         Lookup lookup = PRIVATE;  // FIXME: test more lookups than this one
-        for (Object[] c : HasFields.CASES) {
+        startTest("testSetter");
+        for (Object[] c : HasFields.testCasesFor(testMode|TEST_SETTER)) {
             boolean positive = (c[1] != Error.class);
             testSetter(positive, lookup, c[0], c[1], testMode);
             if (positive)