< prev index next >

test/jdk/java/lang/invoke/MethodHandlesGeneralTest.java

Print this page




   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /* @test

  25  * @summary unit tests for java.lang.invoke.MethodHandles
  26  * @library /test/lib /java/lang/invoke/common
  27  * @compile MethodHandlesTest.java MethodHandlesGeneralTest.java remote/RemoteExample.java
  28  * @run junit/othervm/timeout=2500 -XX:+IgnoreUnrecognizedVMOptions
  29  *                                 -XX:-VerifyDependencies
  30  *                                 -esa
  31  *                                 test.java.lang.invoke.MethodHandlesGeneralTest
  32  */
  33 
  34 package test.java.lang.invoke;
  35 
  36 import org.junit.*;
  37 import test.java.lang.invoke.lib.CodeCacheOverflowProcessor;
  38 import test.java.lang.invoke.remote.RemoteExample;
  39 
  40 import java.lang.invoke.MethodHandle;
  41 import java.lang.invoke.MethodHandleProxies;
  42 import java.lang.invoke.MethodHandles;
  43 import java.lang.invoke.MethodType;
  44 import java.lang.invoke.WrongMethodTypeException;


 647             testGetter(false, lookup,
 648                        new Object[]{ (isStaticN != 0), System.class, "bogus", char.class },
 649                        null, testMode);
 650         }
 651     }
 652 
 653     public void testGetter(boolean positive, MethodHandles.Lookup lookup,
 654                            Object fieldRef, Object value, int testMode) throws Throwable {
 655         testAccessor(positive, lookup, fieldRef, value, testMode);
 656     }
 657 
 658     public void testAccessor(boolean positive0, MethodHandles.Lookup lookup,
 659                              Object fieldRef, Object value, int testMode0) throws Throwable {
 660         if (verbosity >= 4)
 661             System.out.println("testAccessor"+Arrays.deepToString(new Object[]{positive0, lookup, fieldRef, value, testMode0}));
 662         boolean isGetter = ((testMode0 & TEST_SETTER) == 0);
 663         boolean doBound  = ((testMode0 & TEST_BOUND) != 0);
 664         boolean testNPE  = ((testMode0 & TEST_NPE) != 0);
 665         int testMode = testMode0 & ~(TEST_SETTER | TEST_BOUND | TEST_NPE);
 666         boolean positive = positive0 && !testNPE;

 667         boolean isStatic;
 668         Class<?> fclass;
 669         String   fname;
 670         Class<?> ftype;
 671         Field f = (fieldRef instanceof Field ? (Field)fieldRef : null);
 672         if (f != null) {
 673             isStatic = Modifier.isStatic(f.getModifiers());

 674             fclass   = f.getDeclaringClass();
 675             fname    = f.getName();
 676             ftype    = f.getType();
 677         } else {
 678             Object[] scnt = (Object[]) fieldRef;
 679             isStatic = (Boolean)  scnt[0];

 680             fclass   = (Class<?>) scnt[1];
 681             fname    = (String)   scnt[2];
 682             ftype    = (Class<?>) scnt[3];
 683             try {
 684                 f = fclass.getDeclaredField(fname);
 685             } catch (ReflectiveOperationException ex) {
 686                 f = null;
 687             }
 688         }
 689         if (!testModeMatches(testMode, isStatic))  return;
 690         if (f == null && testMode == TEST_UNREFLECT)  return;
 691         if (testNPE && isStatic)  return;
 692         countTest(positive);
 693         MethodType expType;
 694         if (isGetter)
 695             expType = MethodType.methodType(ftype, HasFields.class);
 696         else
 697             expType = MethodType.methodType(void.class, HasFields.class, ftype);
 698         if (isStatic)  expType = expType.dropParameterTypes(0, 1);
 699         Exception noAccess = null;


 703             case TEST_UNREFLECT:   mh = lookup.unreflectGetter(f);                      break;
 704             case TEST_FIND_FIELD:  mh = lookup.findGetter(fclass, fname, ftype);        break;
 705             case TEST_FIND_STATIC: mh = lookup.findStaticGetter(fclass, fname, ftype);  break;
 706             case TEST_SETTER|
 707                  TEST_UNREFLECT:   mh = lookup.unreflectSetter(f);                      break;
 708             case TEST_SETTER|
 709                  TEST_FIND_FIELD:  mh = lookup.findSetter(fclass, fname, ftype);        break;
 710             case TEST_SETTER|
 711                  TEST_FIND_STATIC: mh = lookup.findStaticSetter(fclass, fname, ftype);  break;
 712             default:
 713                 throw new InternalError("testMode="+testMode);
 714             }
 715         } catch (ReflectiveOperationException ex) {
 716             mh = null;
 717             noAccess = ex;
 718             assertExceptionClass(
 719                 (fname.contains("bogus"))
 720                 ?   NoSuchFieldException.class
 721                 :   IllegalAccessException.class,
 722                 noAccess);

 723             if (verbosity >= 5)  ex.printStackTrace(System.out);
 724         }
 725         if (verbosity >= 3)
 726             System.out.println("find"+(isStatic?"Static":"")+(isGetter?"Getter":"Setter")+" "+fclass.getName()+"."+fname+"/"+ftype



 727                                +" => "+mh
 728                                +(noAccess == null ? "" : " !! "+noAccess));
 729         if (positive && !testNPE && noAccess != null)  throw new RuntimeException(noAccess);
 730         assertEquals(positive0 ? "positive test" : "negative test erroneously passed", positive0, mh != null);

 731         if (!positive && !testNPE)  return; // negative access test failed as expected
 732         assertEquals((isStatic ? 0 : 1)+(isGetter ? 0 : 1), mh.type().parameterCount());
 733 
 734 
 735         assertSame(mh.type(), expType);
 736         //assertNameStringContains(mh, fname);  // This does not hold anymore with LFs
 737         HasFields fields = new HasFields();
 738         HasFields fieldsForMH = fields;
 739         if (testNPE)  fieldsForMH = null;  // perturb MH argument to elicit expected error
 740         if (doBound)
 741             mh = mh.bindTo(fieldsForMH);
 742         Object sawValue;
 743         Class<?> vtype = ftype;
 744         if (ftype != int.class)  vtype = Object.class;
 745         if (isGetter) {
 746             mh = mh.asType(mh.type().generic()
 747                            .changeReturnType(vtype));
 748         } else {
 749             int last = mh.type().parameterCount() - 1;
 750             mh = mh.asType(mh.type().generic()
 751                            .changeReturnType(void.class)
 752                            .changeParameterType(last, vtype));
 753         }
 754         if (f != null && f.getDeclaringClass() == HasFields.class) {


 761                 sawValue = null;  // make DA rules happy under try/catch
 762                 try {
 763                     if (isStatic || doBound) {
 764                         if (ftype == int.class)
 765                             sawValue = (int) mh.invokeExact();  // do these exactly
 766                         else
 767                             sawValue = mh.invokeExact();
 768                     } else {
 769                         if (ftype == int.class)
 770                             sawValue = (int) mh.invokeExact((Object) fieldsForMH);
 771                         else
 772                             sawValue = mh.invokeExact((Object) fieldsForMH);
 773                     }
 774                 } catch (RuntimeException ex) {
 775                     if (ex instanceof NullPointerException && testNPE) {
 776                         caughtEx = ex;
 777                         break;
 778                     }
 779                 }
 780                 assertEquals(sawValue, expValue);
 781                 if (f != null && f.getDeclaringClass() == HasFields.class
 782                     && !Modifier.isFinal(f.getModifiers())) {
 783                     Object random = randomArg(ftype);
 784                     f.set(fields, random);
 785                     expValue = random;
 786                 } else {
 787                     break;
 788                 }
 789             }
 790         } else {
 791             for (int i = 0; i <= 1; i++) {
 792                 Object putValue = randomArg(ftype);
 793                 try {
 794                     if (isStatic || doBound) {
 795                         if (ftype == int.class)
 796                             mh.invokeExact((int)putValue);  // do these exactly
 797                         else
 798                             mh.invokeExact(putValue);
 799                     } else {
 800                         if (ftype == int.class)
 801                             mh.invokeExact((Object) fieldsForMH, (int)putValue);
 802                         else
 803                             mh.invokeExact((Object) fieldsForMH, putValue);
 804                     }
 805                 } catch (RuntimeException ex) {
 806                     if (ex instanceof NullPointerException && testNPE) {
 807                         caughtEx = ex;
 808                         break;
 809                     }
 810                 }
 811                 if (f != null && f.getDeclaringClass() == HasFields.class) {
 812                     assertEquals(f.get(fields), putValue);
 813                 }
 814             }
 815         }
 816         if (f != null && f.getDeclaringClass() == HasFields.class) {
 817             f.set(fields, value);  // put it back
 818         }
 819         if (testNPE) {
 820             if (caughtEx == null || !(caughtEx instanceof NullPointerException))
 821                 throw new RuntimeException("failed to catch NPE exception"+(caughtEx == null ? " (caughtEx=null)" : ""), caughtEx);
 822             caughtEx = null;  // nullify expected exception
 823         }
 824         if (caughtEx != null) {
 825             throw new RuntimeException("unexpected exception", caughtEx);
 826         }
 827     }
 828 
 829     @Test
 830     public void testUnreflectSetter() throws Throwable {
 831         CodeCacheOverflowProcessor.runMHTest(this::testUnreflectSetter0);
 832     }
 833 
 834     public void testUnreflectSetter0() throws Throwable {
 835         if (CAN_SKIP_WORKING)  return;
 836         startTest("unreflectSetter");
 837         testSetter(TEST_UNREFLECT);


 845     public void testFindSetter0() throws Throwable {
 846         if (CAN_SKIP_WORKING)  return;
 847         startTest("findSetter");
 848         testSetter(TEST_FIND_FIELD);
 849         testSetter(TEST_FIND_FIELD | TEST_BOUND);
 850     }
 851 
 852     @Test
 853     public void testFindStaticSetter() throws Throwable {
 854         CodeCacheOverflowProcessor.runMHTest(this::testFindStaticSetter0);
 855     }
 856 
 857     public void testFindStaticSetter0() throws Throwable {
 858         if (CAN_SKIP_WORKING)  return;
 859         startTest("findStaticSetter");
 860         testSetter(TEST_FIND_STATIC);
 861     }
 862 
 863     public void testSetter(int testMode) throws Throwable {
 864         Lookup lookup = PRIVATE;  // FIXME: test more lookups than this one
 865         startTest("unreflectSetter");
 866         for (Object[] c : HasFields.CASES) {
 867             boolean positive = (c[1] != Error.class);
 868             testSetter(positive, lookup, c[0], c[1], testMode);
 869             if (positive)
 870                 testSetter(positive, lookup, c[0], c[1], testMode | TEST_NPE);
 871         }
 872         for (int isStaticN = 0; isStaticN <= 1; isStaticN++) {
 873             testSetter(false, lookup,
 874                        new Object[]{ (isStaticN != 0), System.class, "bogus", char.class },
 875                        null, testMode);
 876         }
 877     }
 878 
 879     public void testSetter(boolean positive, MethodHandles.Lookup lookup,
 880                            Object fieldRef, Object value, int testMode) throws Throwable {
 881         testAccessor(positive, lookup, fieldRef, value, testMode | TEST_SETTER);
 882     }
 883 
 884     @Test
 885     public void testArrayElementGetter() throws Throwable {




   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /* @test
  25  * @bug 8216558
  26  * @summary unit tests for java.lang.invoke.MethodHandles
  27  * @library /test/lib /java/lang/invoke/common
  28  * @compile MethodHandlesTest.java MethodHandlesGeneralTest.java remote/RemoteExample.java
  29  * @run junit/othervm/timeout=2500 -XX:+IgnoreUnrecognizedVMOptions
  30  *                                 -XX:-VerifyDependencies
  31  *                                 -esa
  32  *                                 test.java.lang.invoke.MethodHandlesGeneralTest
  33  */
  34 
  35 package test.java.lang.invoke;
  36 
  37 import org.junit.*;
  38 import test.java.lang.invoke.lib.CodeCacheOverflowProcessor;
  39 import test.java.lang.invoke.remote.RemoteExample;
  40 
  41 import java.lang.invoke.MethodHandle;
  42 import java.lang.invoke.MethodHandleProxies;
  43 import java.lang.invoke.MethodHandles;
  44 import java.lang.invoke.MethodType;
  45 import java.lang.invoke.WrongMethodTypeException;


 648             testGetter(false, lookup,
 649                        new Object[]{ (isStaticN != 0), System.class, "bogus", char.class },
 650                        null, testMode);
 651         }
 652     }
 653 
 654     public void testGetter(boolean positive, MethodHandles.Lookup lookup,
 655                            Object fieldRef, Object value, int testMode) throws Throwable {
 656         testAccessor(positive, lookup, fieldRef, value, testMode);
 657     }
 658 
 659     public void testAccessor(boolean positive0, MethodHandles.Lookup lookup,
 660                              Object fieldRef, Object value, int testMode0) throws Throwable {
 661         if (verbosity >= 4)
 662             System.out.println("testAccessor"+Arrays.deepToString(new Object[]{positive0, lookup, fieldRef, value, testMode0}));
 663         boolean isGetter = ((testMode0 & TEST_SETTER) == 0);
 664         boolean doBound  = ((testMode0 & TEST_BOUND) != 0);
 665         boolean testNPE  = ((testMode0 & TEST_NPE) != 0);
 666         int testMode = testMode0 & ~(TEST_SETTER | TEST_BOUND | TEST_NPE);
 667         boolean positive = positive0 && !testNPE;
 668         boolean isFinal;
 669         boolean isStatic;
 670         Class<?> fclass;
 671         String   fname;
 672         Class<?> ftype;
 673         Field f = (fieldRef instanceof Field ? (Field)fieldRef : null);
 674         if (f != null) {
 675             isStatic = Modifier.isStatic(f.getModifiers());
 676             isFinal  = Modifier.isFinal(f.getModifiers());
 677             fclass   = f.getDeclaringClass();
 678             fname    = f.getName();
 679             ftype    = f.getType();
 680         } else {
 681             Object[] scnt = (Object[]) fieldRef;
 682             isStatic = (Boolean)  scnt[0];
 683             isFinal  = false;
 684             fclass   = (Class<?>) scnt[1];
 685             fname    = (String)   scnt[2];
 686             ftype    = (Class<?>) scnt[3];
 687             try {
 688                 f = fclass.getDeclaredField(fname);
 689             } catch (ReflectiveOperationException ex) {
 690                 f = null;
 691             }
 692         }
 693         if (!testModeMatches(testMode, isStatic))  return;
 694         if (f == null && testMode == TEST_UNREFLECT)  return;
 695         if (testNPE && isStatic)  return;
 696         countTest(positive);
 697         MethodType expType;
 698         if (isGetter)
 699             expType = MethodType.methodType(ftype, HasFields.class);
 700         else
 701             expType = MethodType.methodType(void.class, HasFields.class, ftype);
 702         if (isStatic)  expType = expType.dropParameterTypes(0, 1);
 703         Exception noAccess = null;


 707             case TEST_UNREFLECT:   mh = lookup.unreflectGetter(f);                      break;
 708             case TEST_FIND_FIELD:  mh = lookup.findGetter(fclass, fname, ftype);        break;
 709             case TEST_FIND_STATIC: mh = lookup.findStaticGetter(fclass, fname, ftype);  break;
 710             case TEST_SETTER|
 711                  TEST_UNREFLECT:   mh = lookup.unreflectSetter(f);                      break;
 712             case TEST_SETTER|
 713                  TEST_FIND_FIELD:  mh = lookup.findSetter(fclass, fname, ftype);        break;
 714             case TEST_SETTER|
 715                  TEST_FIND_STATIC: mh = lookup.findStaticSetter(fclass, fname, ftype);  break;
 716             default:
 717                 throw new InternalError("testMode="+testMode);
 718             }
 719         } catch (ReflectiveOperationException ex) {
 720             mh = null;
 721             noAccess = ex;
 722             assertExceptionClass(
 723                 (fname.contains("bogus"))
 724                 ?   NoSuchFieldException.class
 725                 :   IllegalAccessException.class,
 726                 noAccess);
 727             if (((testMode0 & TEST_SETTER) != 0) && (isFinal && isStatic)) return; // Final static field setter test failed as intended.
 728             if (verbosity >= 5)  ex.printStackTrace(System.out);
 729         }
 730         if (verbosity >= 3)
 731             System.out.println((((testMode0 & TEST_UNREFLECT) != 0)?"unreflect":"find")
 732                               +(((testMode0 & TEST_FIND_STATIC) != 0)?"Static":"")
 733                               +(isGetter?"Getter":"Setter")
 734                               +" "+fclass.getName()+"."+fname+"/"+ftype
 735                               +" => "+mh
 736                               +(noAccess == null ? "" : " !! "+noAccess));
 737         if (positive && !testNPE && noAccess != null)  throw new RuntimeException(noAccess);
 738         assertEquals(positive0 ? "positive test" : "negative test erroneously passed", positive0, mh != null);
 739         assertFalse("Setter methods should throw an exception if passed a final static field.", ((testMode0 & TEST_SETTER) != 0) && (isFinal && isStatic));
 740         if (!positive && !testNPE)  return; // negative access test failed as expected
 741         assertEquals((isStatic ? 0 : 1)+(isGetter ? 0 : 1), mh.type().parameterCount());


 742         assertSame(mh.type(), expType);
 743         //assertNameStringContains(mh, fname);  // This does not hold anymore with LFs
 744         HasFields fields = new HasFields();
 745         HasFields fieldsForMH = fields;
 746         if (testNPE)  fieldsForMH = null;  // perturb MH argument to elicit expected error
 747         if (doBound)
 748             mh = mh.bindTo(fieldsForMH);
 749         Object sawValue;
 750         Class<?> vtype = ftype;
 751         if (ftype != int.class)  vtype = Object.class;
 752         if (isGetter) {
 753             mh = mh.asType(mh.type().generic()
 754                            .changeReturnType(vtype));
 755         } else {
 756             int last = mh.type().parameterCount() - 1;
 757             mh = mh.asType(mh.type().generic()
 758                            .changeReturnType(void.class)
 759                            .changeParameterType(last, vtype));
 760         }
 761         if (f != null && f.getDeclaringClass() == HasFields.class) {


 768                 sawValue = null;  // make DA rules happy under try/catch
 769                 try {
 770                     if (isStatic || doBound) {
 771                         if (ftype == int.class)
 772                             sawValue = (int) mh.invokeExact();  // do these exactly
 773                         else
 774                             sawValue = mh.invokeExact();
 775                     } else {
 776                         if (ftype == int.class)
 777                             sawValue = (int) mh.invokeExact((Object) fieldsForMH);
 778                         else
 779                             sawValue = mh.invokeExact((Object) fieldsForMH);
 780                     }
 781                 } catch (RuntimeException ex) {
 782                     if (ex instanceof NullPointerException && testNPE) {
 783                         caughtEx = ex;
 784                         break;
 785                     }
 786                 }
 787                 assertEquals(sawValue, expValue);
 788                 if (f != null && f.getDeclaringClass() == HasFields.class && !isFinal) {

 789                     Object random = randomArg(ftype);
 790                     f.set(fields, random);
 791                     expValue = random;
 792                 } else {
 793                     break;
 794                 }
 795             }
 796         } else {
 797             for (int i = 0; i <= 1; i++) {
 798                 Object putValue = randomArg(ftype);
 799                 try {
 800                     if (isStatic || doBound) {
 801                         if (ftype == int.class)
 802                             mh.invokeExact((int)putValue);  // do these exactly
 803                         else
 804                             mh.invokeExact(putValue);
 805                     } else {
 806                         if (ftype == int.class)
 807                             mh.invokeExact((Object) fieldsForMH, (int)putValue);
 808                         else
 809                             mh.invokeExact((Object) fieldsForMH, putValue);
 810                     }
 811                 } catch (RuntimeException ex) {
 812                     if (ex instanceof NullPointerException && testNPE) {
 813                         caughtEx = ex;
 814                         break;
 815                     }
 816                 }
 817                 if (f != null && f.getDeclaringClass() == HasFields.class) {
 818                     assertEquals(f.get(fields), putValue);
 819                 }
 820             }
 821         }
 822         if ((f != null) && (f.getDeclaringClass() == HasFields.class) && !isFinal) {
 823             f.set(fields, value);  // put it back if we changed it.
 824         }
 825         if (testNPE) {
 826             if (caughtEx == null || !(caughtEx instanceof NullPointerException))
 827                 throw new RuntimeException("failed to catch NPE exception"+(caughtEx == null ? " (caughtEx=null)" : ""), caughtEx);
 828             caughtEx = null;  // nullify expected exception
 829         }
 830         if (caughtEx != null) {
 831             throw new RuntimeException("unexpected exception", caughtEx);
 832         }
 833     }
 834 
 835     @Test
 836     public void testUnreflectSetter() throws Throwable {
 837         CodeCacheOverflowProcessor.runMHTest(this::testUnreflectSetter0);
 838     }
 839 
 840     public void testUnreflectSetter0() throws Throwable {
 841         if (CAN_SKIP_WORKING)  return;
 842         startTest("unreflectSetter");
 843         testSetter(TEST_UNREFLECT);


 851     public void testFindSetter0() throws Throwable {
 852         if (CAN_SKIP_WORKING)  return;
 853         startTest("findSetter");
 854         testSetter(TEST_FIND_FIELD);
 855         testSetter(TEST_FIND_FIELD | TEST_BOUND);
 856     }
 857 
 858     @Test
 859     public void testFindStaticSetter() throws Throwable {
 860         CodeCacheOverflowProcessor.runMHTest(this::testFindStaticSetter0);
 861     }
 862 
 863     public void testFindStaticSetter0() throws Throwable {
 864         if (CAN_SKIP_WORKING)  return;
 865         startTest("findStaticSetter");
 866         testSetter(TEST_FIND_STATIC);
 867     }
 868 
 869     public void testSetter(int testMode) throws Throwable {
 870         Lookup lookup = PRIVATE;  // FIXME: test more lookups than this one

 871         for (Object[] c : HasFields.CASES) {
 872             boolean positive = (c[1] != Error.class);
 873             testSetter(positive, lookup, c[0], c[1], testMode);
 874             if (positive)
 875                 testSetter(positive, lookup, c[0], c[1], testMode | TEST_NPE);
 876         }
 877         for (int isStaticN = 0; isStaticN <= 1; isStaticN++) {
 878             testSetter(false, lookup,
 879                        new Object[]{ (isStaticN != 0), System.class, "bogus", char.class },
 880                        null, testMode);
 881         }
 882     }
 883 
 884     public void testSetter(boolean positive, MethodHandles.Lookup lookup,
 885                            Object fieldRef, Object value, int testMode) throws Throwable {
 886         testAccessor(positive, lookup, fieldRef, value, testMode | TEST_SETTER);
 887     }
 888 
 889     @Test
 890     public void testArrayElementGetter() throws Throwable {


< prev index next >