Duplicate :
|
|
Duplicate :
|
|
Duplicate :
|
|
Duplicate :
|
|
Duplicate :
|
|
Duplicate :
|
|
Relates :
|
|
Relates :
|
MethodHandles$Lookup.findStatic[S|G]etter throws InternalError if SecurityManager is set. Minimized test: =============== $ cat test.java import java.lang.invoke.*; public class test { public static void main(String[] args) throws Throwable { System.setSecurityManager(new SM()); MethodHandle mh = MethodHandles.lookup().findStaticSetter( GetSet.class, "sf1", int.class); } } class SM extends SecurityManager { protected SM() { super(); } } class GetSet { static int sf1; } Minimized test output: ====================== $ javac test.java $ java -showversion test java version "1.7.0-ea" Java(TM) SE Runtime Environment (build 1.7.0-ea-b140) Java HotSpot(TM) Server VM (build 21.0-b10, mixed mode) Exception in thread "main" java.lang.InternalError: uncaught exception at java.lang.invoke.MethodHandleStatics.uncaughtException(MethodHandleStatics.java:84) at java.lang.invoke.MethodHandleImpl$FieldAccessor.staticBase(MethodHandleImpl.java:314) at java.lang.invoke.MethodHandleImpl$FieldAccessor.<init>(MethodHandleImpl.java:278) at java.lang.invoke.MethodHandleImpl.accessField(MethodHandleImpl.java:241) at java.lang.invoke.MethodHandles$Lookup.makeAccessor(MethodHandles.java:1103) at java.lang.invoke.MethodHandles$Lookup.makeAccessor(MethodHandles.java:1094) at java.lang.invoke.MethodHandles$Lookup.findStaticSetter(MethodHandles.java:785) at test.main(test.java:7) Caused by: java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessDeclaredMembers") at java.security.AccessControlContext.checkPermission(AccessControlContext.java:366) at java.security.AccessController.checkPermission(AccessController.java:555) at java.lang.SecurityManager.checkPermission(SecurityManager.java:549) at java.lang.SecurityManager.checkMemberAccess(SecurityManager.java:1679) at java.lang.Class.checkMemberAccess(Class.java:2174) at java.lang.Class.getDeclaredField(Class.java:1896) at java.lang.invoke.MethodHandleImpl$FieldAccessor.staticBase(MethodHandleImpl.java:311) ... 6 more MethodHandle.invoke[Exact|Generic] doesn't throw UnsupportedOperationException if invoked via java.lang.reflect.Method.invoke. The javadoc for the MethodHandle invokeExact/invokeGeneric methods states as follows: "When this method is observed via the Core Reflection API, it will appear as a single native method, taking an object array and returning an object. If this native method is invoked directly via Method.invoke ... it will throw an UnsupportedOperationException." However, InvocationTargetException is thrown in such cases. Minimized test: =============== $ cat test.java import java.lang.reflect.*; import java.lang.invoke.*; public class test { public static void main(String[] args) throws Throwable { MethodHandle target = MethodHandles.lookup().findVirtual( MethodHandle.class, "invokeExact", MethodType.methodType(Object.class, Object[].class)); Method method = MethodHandle.class.getDeclaredMethod( "invokeExact", Object[].class); //Method method = MethodHandle.class.getDeclaredMethod( // "invokeGeneric", Object[].class); Object[] params = new Object[1]; method.invoke(target, params); } } Minimized test output: ======================== $ javac test.java $ java -verify test Exception in thread "main" java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at test.main(test.java:15) Caused by: java.lang.UnsatisfiedLinkError: java.lang.invoke.MethodHandle.invokeExact([Ljava/lang/Object;)Ljava/lang/Object; at java.lang.invoke.MethodHandle.invokeExact(Native Method) ... 5 more MethodType.methodType(Class rtype, Class[] ptypes) doesn't throw NPE if ptypes is null. Minimized test: =============== $ cat Test.java import java.lang.invoke.*; import java.util.Arrays; public class Test { public static void main(String[] args) throws Exception { Object[][] data = new Object[][] { { (Class) null, (Class[]) null }, { (Class) null, new Class[]{Object.class} }, { Object.class, new Class[]{ null} }, { Object.class, new Class[]{Object.class, (Class) null} }, { Object.class, (Class[]) null } }; for (int i = 0; i < data.length; i++) { Class<?> rtype = (Class) data[i][0]; Class<?>[] ptypes = (Class[]) data[i][1]; try { MethodType.methodType(rtype, ptypes); System.out.println("FAILED: NPE not thrown for " + rtype + ", " + Arrays.toString(ptypes)); } catch(NullPointerException ok) { System.out.println("OK: NPE is thrown for " + rtype + ", " + Arrays.toString(ptypes)); } } } } Minimized test output: ======================== $ java -showversion -verify Test java version "1.7.0-ea" Java(TM) SE Runtime Environment (build 1.7.0-ea-b138) Java HotSpot(TM) Server VM (build 21.0-b08, mixed mode) OK: NPE is thrown for null, null OK: NPE is thrown for null, [class java.lang.Object] OK: NPE is thrown for class java.lang.Object, [null] OK: NPE is thrown for class java.lang.Object, [class java.lang.Object, null] FAILED: NPE not thrown for class java.lang.Object, null MethodType.fromMethodDescriptorString unexpectedly accepts both "binary names"/"internal form of binary names". Minimized test: =============== $ cat Test.java import java.lang.invoke.*; public class Test { public static void main(String[] args) throws Exception { for (String d : new String[] {"(Ljava/lang/Object;)V", "(Ljava.lang.Object;)V"}) { MethodType.fromMethodDescriptorString(d, null); System.out.println("OK"); } } } Minimized test output: ====================== $ java -showversion -verify Test java version "1.7.0-ea" Java(TM) SE Runtime Environment (build 1.7.0-ea-b138) Java HotSpot(TM) Server VM (build 21.0-b08, mixed mode) OK OK MethodHandles.Lookup.find[G|S]etter throws unexpected IllegalAccessException. Minimized test: =============== $ cat test.java import java.lang.invoke.MethodType; import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodHandles.Lookup.*; public class test { public static void main(String[] args) throws Throwable { lookup().findGetter(TestCls.class, "f2", int.class); TestCls c = new TestCls(); c.f2 = 1; } } class TestCls { protected int f2 = 2; } Minimized test output: ====================== $ java -showversion test java version "1.7.0-ea" Java(TM) SE Runtime Environment (build 1.7.0-ea-b140) Java HotSpot(TM) Server VM (build 21.0-b10, mixed mode) Exception in thread "main" java.lang.IllegalAccessException: caller class must be a subclass below the method: TestCls.f2/int, from class test at java.lang.invoke.MemberName.makeAccessException(MemberName.java:507) at java.lang.invoke.MethodHandles$Lookup.restrictReceiver(MethodHandles.java:1078) at java.lang.invoke.MethodHandles$Lookup.restrictProtectedReceiver(MethodHandles.java:1072) at java.lang.invoke.MethodHandles$Lookup.makeAccessor(MethodHandles.java:1104) at java.lang.invoke.MethodHandles$Lookup.makeAccessor(MethodHandles.java:1094) at java.lang.invoke.MethodHandles$Lookup.findGetter(MethodHandles.java:724) at test.main(test.java:8) MethodHandle.asCollector throws undocumented ArrayIndexOutOfBoundsException instead of IllegalArgumentException for invalid arrayLength values (negative or >= 256). Minimized test: =============== $ cat test.java import java.lang.invoke.*; import java.util.Arrays; public class test { public static void main(String[] args) throws Throwable { MethodHandle dts = MethodHandles.publicLookup().findStatic( Arrays.class, "deepToString", MethodType.methodType(String.class, Object[].class)); dts.asCollector(Object[].class, -1); } } Minimized test output: ====================== $ openjdk7-mlvm/solaris-i586/bin/java -verify test Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1 at sun.invoke.util.ValueConversions.varargsArray(ValueConversions.java:1068) at sun.invoke.util.ValueConversions.varargsArray(ValueConversions.java:1144) at java.lang.invoke.MethodHandle.asCollector(MethodHandle.java:872) at test.main(test.java:10) MethodHandle.bindTo((Object) null) throws InternalError. Minimized test: =============== $ cat test.java import java.lang.invoke.*; import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; public class test { public static void main(String[] args) throws Throwable { MethodHandle target = publicLookup().findVirtual( String.class, "toString", methodType(String.class)); MethodHandle bt = target.bindTo((Object) null); } } Minimized test output: ====================== $ java -verify test Exception in thread "main" java.lang.InternalError at java.lang.invoke.MethodHandleNatives.init(Native Method) at java.lang.invoke.BoundMethodHandle.initTarget(BoundMethodHandle.java:81) at java.lang.invoke.BoundMethodHandle.<init>(BoundMethodHandle.java:76) at java.lang.invoke.BoundMethodHandle.<init>(BoundMethodHandle.java:61) at java.lang.invoke.MethodHandleImpl.bindReceiver(MethodHandleImpl.java:501) at java.lang.invoke.MethodHandle.bindTo(MethodHandle.java:1125) at test.main(test.java:10)
|