20 * or visit www.oracle.com if you need additional information or have any |
20 * or visit www.oracle.com if you need additional information or have any |
21 * questions. |
21 * questions. |
22 */ |
22 */ |
23 |
23 |
24 /* @test |
24 /* @test |
|
25 * @bug 8216558 |
25 * @summary unit tests for java.lang.invoke.MethodHandles |
26 * @summary unit tests for java.lang.invoke.MethodHandles |
26 * @library /test/lib /java/lang/invoke/common |
27 * @library /test/lib /java/lang/invoke/common |
27 * @compile MethodHandlesTest.java MethodHandlesGeneralTest.java remote/RemoteExample.java |
28 * @compile MethodHandlesTest.java MethodHandlesGeneralTest.java remote/RemoteExample.java |
28 * @run junit/othervm/timeout=2500 -XX:+IgnoreUnrecognizedVMOptions |
29 * @run junit/othervm/timeout=2500 -XX:+IgnoreUnrecognizedVMOptions |
29 * -XX:-VerifyDependencies |
30 * -XX:-VerifyDependencies |
662 boolean isGetter = ((testMode0 & TEST_SETTER) == 0); |
663 boolean isGetter = ((testMode0 & TEST_SETTER) == 0); |
663 boolean doBound = ((testMode0 & TEST_BOUND) != 0); |
664 boolean doBound = ((testMode0 & TEST_BOUND) != 0); |
664 boolean testNPE = ((testMode0 & TEST_NPE) != 0); |
665 boolean testNPE = ((testMode0 & TEST_NPE) != 0); |
665 int testMode = testMode0 & ~(TEST_SETTER | TEST_BOUND | TEST_NPE); |
666 int testMode = testMode0 & ~(TEST_SETTER | TEST_BOUND | TEST_NPE); |
666 boolean positive = positive0 && !testNPE; |
667 boolean positive = positive0 && !testNPE; |
|
668 boolean isFinal; |
667 boolean isStatic; |
669 boolean isStatic; |
668 Class<?> fclass; |
670 Class<?> fclass; |
669 String fname; |
671 String fname; |
670 Class<?> ftype; |
672 Class<?> ftype; |
671 Field f = (fieldRef instanceof Field ? (Field)fieldRef : null); |
673 Field f = (fieldRef instanceof Field ? (Field)fieldRef : null); |
672 if (f != null) { |
674 if (f != null) { |
673 isStatic = Modifier.isStatic(f.getModifiers()); |
675 isStatic = Modifier.isStatic(f.getModifiers()); |
|
676 isFinal = Modifier.isFinal(f.getModifiers()); |
674 fclass = f.getDeclaringClass(); |
677 fclass = f.getDeclaringClass(); |
675 fname = f.getName(); |
678 fname = f.getName(); |
676 ftype = f.getType(); |
679 ftype = f.getType(); |
677 } else { |
680 } else { |
678 Object[] scnt = (Object[]) fieldRef; |
681 Object[] scnt = (Object[]) fieldRef; |
679 isStatic = (Boolean) scnt[0]; |
682 isStatic = (Boolean) scnt[0]; |
|
683 isFinal = false; |
680 fclass = (Class<?>) scnt[1]; |
684 fclass = (Class<?>) scnt[1]; |
681 fname = (String) scnt[2]; |
685 fname = (String) scnt[2]; |
682 ftype = (Class<?>) scnt[3]; |
686 ftype = (Class<?>) scnt[3]; |
683 try { |
687 try { |
684 f = fclass.getDeclaredField(fname); |
688 f = fclass.getDeclaredField(fname); |
718 assertExceptionClass( |
722 assertExceptionClass( |
719 (fname.contains("bogus")) |
723 (fname.contains("bogus")) |
720 ? NoSuchFieldException.class |
724 ? NoSuchFieldException.class |
721 : IllegalAccessException.class, |
725 : IllegalAccessException.class, |
722 noAccess); |
726 noAccess); |
|
727 if (((testMode0 & TEST_SETTER) != 0) && (isFinal && isStatic)) return; // Final static field setter test failed as intended. |
723 if (verbosity >= 5) ex.printStackTrace(System.out); |
728 if (verbosity >= 5) ex.printStackTrace(System.out); |
724 } |
729 } |
725 if (verbosity >= 3) |
730 if (verbosity >= 3) |
726 System.out.println("find"+(isStatic?"Static":"")+(isGetter?"Getter":"Setter")+" "+fclass.getName()+"."+fname+"/"+ftype |
731 System.out.println((((testMode0 & TEST_UNREFLECT) != 0)?"unreflect":"find") |
727 +" => "+mh |
732 +(((testMode0 & TEST_FIND_STATIC) != 0)?"Static":"") |
728 +(noAccess == null ? "" : " !! "+noAccess)); |
733 +(isGetter?"Getter":"Setter") |
|
734 +" "+fclass.getName()+"."+fname+"/"+ftype |
|
735 +" => "+mh |
|
736 +(noAccess == null ? "" : " !! "+noAccess)); |
729 if (positive && !testNPE && noAccess != null) throw new RuntimeException(noAccess); |
737 if (positive && !testNPE && noAccess != null) throw new RuntimeException(noAccess); |
730 assertEquals(positive0 ? "positive test" : "negative test erroneously passed", positive0, mh != null); |
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)); |
731 if (!positive && !testNPE) return; // negative access test failed as expected |
740 if (!positive && !testNPE) return; // negative access test failed as expected |
732 assertEquals((isStatic ? 0 : 1)+(isGetter ? 0 : 1), mh.type().parameterCount()); |
741 assertEquals((isStatic ? 0 : 1)+(isGetter ? 0 : 1), mh.type().parameterCount()); |
733 |
|
734 |
|
735 assertSame(mh.type(), expType); |
742 assertSame(mh.type(), expType); |
736 //assertNameStringContains(mh, fname); // This does not hold anymore with LFs |
743 //assertNameStringContains(mh, fname); // This does not hold anymore with LFs |
737 HasFields fields = new HasFields(); |
744 HasFields fields = new HasFields(); |
738 HasFields fieldsForMH = fields; |
745 HasFields fieldsForMH = fields; |
739 if (testNPE) fieldsForMH = null; // perturb MH argument to elicit expected error |
746 if (testNPE) fieldsForMH = null; // perturb MH argument to elicit expected error |
776 caughtEx = ex; |
783 caughtEx = ex; |
777 break; |
784 break; |
778 } |
785 } |
779 } |
786 } |
780 assertEquals(sawValue, expValue); |
787 assertEquals(sawValue, expValue); |
781 if (f != null && f.getDeclaringClass() == HasFields.class |
788 if (f != null && f.getDeclaringClass() == HasFields.class && !isFinal) { |
782 && !Modifier.isFinal(f.getModifiers())) { |
|
783 Object random = randomArg(ftype); |
789 Object random = randomArg(ftype); |
784 f.set(fields, random); |
790 f.set(fields, random); |
785 expValue = random; |
791 expValue = random; |
786 } else { |
792 } else { |
787 break; |
793 break; |
811 if (f != null && f.getDeclaringClass() == HasFields.class) { |
817 if (f != null && f.getDeclaringClass() == HasFields.class) { |
812 assertEquals(f.get(fields), putValue); |
818 assertEquals(f.get(fields), putValue); |
813 } |
819 } |
814 } |
820 } |
815 } |
821 } |
816 if (f != null && f.getDeclaringClass() == HasFields.class) { |
822 if ((f != null) && (f.getDeclaringClass() == HasFields.class) && !isFinal) { |
817 f.set(fields, value); // put it back |
823 f.set(fields, value); // put it back if we changed it. |
818 } |
824 } |
819 if (testNPE) { |
825 if (testNPE) { |
820 if (caughtEx == null || !(caughtEx instanceof NullPointerException)) |
826 if (caughtEx == null || !(caughtEx instanceof NullPointerException)) |
821 throw new RuntimeException("failed to catch NPE exception"+(caughtEx == null ? " (caughtEx=null)" : ""), caughtEx); |
827 throw new RuntimeException("failed to catch NPE exception"+(caughtEx == null ? " (caughtEx=null)" : ""), caughtEx); |
822 caughtEx = null; // nullify expected exception |
828 caughtEx = null; // nullify expected exception |
860 testSetter(TEST_FIND_STATIC); |
866 testSetter(TEST_FIND_STATIC); |
861 } |
867 } |
862 |
868 |
863 public void testSetter(int testMode) throws Throwable { |
869 public void testSetter(int testMode) throws Throwable { |
864 Lookup lookup = PRIVATE; // FIXME: test more lookups than this one |
870 Lookup lookup = PRIVATE; // FIXME: test more lookups than this one |
865 startTest("unreflectSetter"); |
|
866 for (Object[] c : HasFields.CASES) { |
871 for (Object[] c : HasFields.CASES) { |
867 boolean positive = (c[1] != Error.class); |
872 boolean positive = (c[1] != Error.class); |
868 testSetter(positive, lookup, c[0], c[1], testMode); |
873 testSetter(positive, lookup, c[0], c[1], testMode); |
869 if (positive) |
874 if (positive) |
870 testSetter(positive, lookup, c[0], c[1], testMode | TEST_NPE); |
875 testSetter(positive, lookup, c[0], c[1], testMode | TEST_NPE); |