--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java Wed Jan 30 11:33:51 2013 +0100
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java Thu Jan 24 16:45:38 2013 -0800
@@ -476,6 +476,8 @@
case "getProxyClass":
case "newProxyInstance":
return defc == java.lang.reflect.Proxy.class;
+ case "asInterfaceInstance":
+ return defc == java.lang.invoke.MethodHandleProxies.class;
case "getBundle":
case "clearCache":
return defc == java.util.ResourceBundle.class;
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleProxies.java Wed Jan 30 11:33:51 2013 +0100
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleProxies.java Thu Jan 24 16:45:38 2013 -0800
@@ -141,12 +141,15 @@
<T> T asInterfaceInstance(final Class<T> intfc, final MethodHandle target) {
if (!intfc.isInterface() || !Modifier.isPublic(intfc.getModifiers()))
throw new IllegalArgumentException("not a public interface: "+intfc.getName());
- SecurityManager smgr = System.getSecurityManager();
- if (smgr != null) {
+ final MethodHandle mh;
+ if (System.getSecurityManager() != null) {
final int CALLER_FRAME = 2; // 0: Reflection, 1: asInterfaceInstance, 2: caller
final Class<?> caller = Reflection.getCallerClass(CALLER_FRAME);
- final ClassLoader ccl = caller.getClassLoader();
+ final ClassLoader ccl = caller != null ? caller.getClassLoader() : null;
ReflectUtil.checkProxyPackageAccess(ccl, intfc);
+ mh = ccl != null ? bindCaller(target, caller) : target;
+ } else {
+ mh = target;
}
ClassLoader proxyLoader = intfc.getClassLoader();
if (proxyLoader == null) {
@@ -160,7 +163,7 @@
for (int i = 0; i < methods.length; i++) {
Method sm = methods[i];
MethodType smMT = MethodType.methodType(sm.getReturnType(), sm.getParameterTypes());
- MethodHandle checkTarget = target.asType(smMT); // make throw WMT
+ MethodHandle checkTarget = mh.asType(smMT); // make throw WMT
checkTarget = checkTarget.asType(checkTarget.type().changeReturnType(Object.class));
vaTargets[i] = checkTarget.asSpreader(Object[].class, smMT.parameterCount());
}
@@ -183,8 +186,8 @@
}
};
- Object proxy;
- if (smgr != null) {
+ final Object proxy;
+ if (System.getSecurityManager() != null) {
// sun.invoke.WrapperInstance is a restricted interface not accessible
// by any non-null class loader.
final ClassLoader loader = proxyLoader;
@@ -204,6 +207,16 @@
return intfc.cast(proxy);
}
+ private static MethodHandle bindCaller(MethodHandle target, Class<?> hostClass) {
+ MethodHandle cbmh = MethodHandleImpl.bindCaller(target, hostClass);
+ if (target.isVarargsCollector()) {
+ MethodType type = cbmh.type();
+ int arity = type.parameterCount();
+ return cbmh.asVarargsCollector(type.parameterType(arity-1));
+ }
+ return cbmh;
+ }
+
/**
* Determines if the given object was produced by a call to {@link #asInterfaceInstance asInterfaceInstance}.
* @param x any reference