提交 be6ddade 编写于 作者: J jrose

7013730: JSR 292 reflective operations should report errors with standard exception types

Summary: remove NoAccessException, replace it by ReflectiveOperationException subtypes; adjust javadoc of exceptions
Reviewed-by: twisti
上级 d6a13e54
......@@ -228,7 +228,7 @@ public class CallSite {
try {
GET_TARGET = MethodHandles.Lookup.IMPL_LOOKUP.
findVirtual(CallSite.class, "getTarget", MethodType.methodType(MethodHandle.class));
} catch (NoAccessException ignore) {
} catch (ReflectiveOperationException ignore) {
throw new InternalError();
}
}
......
......@@ -88,7 +88,7 @@ public class Linkage {
MethodHandle bootstrapMethod;
try {
bootstrapMethod = lookup.findStatic(runtime, name, BOOTSTRAP_METHOD_TYPE);
} catch (NoAccessException ex) {
} catch (ReflectiveOperationException ex) {
throw new IllegalArgumentException("no such bootstrap method in "+runtime+": "+name, ex);
}
MethodHandleImpl.registerBootstrap(IMPL_TOKEN, callerClass, bootstrapMethod);
......
/*
* Copyright (c) 2008, 2010, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.dyn;
/**
* Thrown to indicate that a caller has attempted to create a method handle
* which accesses a field, method, or class to which the caller does not have access.
* This unchecked exception is analogous to {@link IllegalAccessException},
* which is a checked exception thrown when reflective invocation fails
* because of an access check. With method handles, this same access
* checking is performed by the {@link MethodHandles.Lookup lookup object}
* on behalf of the method handle creator,
* at the time of creation.
* @author John Rose, JSR 292 EG
* @since 1.7
*/
public class NoAccessException extends ReflectiveOperationException {
private static final long serialVersionUID = 292L;
/**
* Constructs a {@code NoAccessException} with no detail message.
*/
public NoAccessException() {
super();
}
/**
* Constructs a {@code NoAccessException} with the specified
* detail message.
*
* @param s the detail message
*/
public NoAccessException(String s) {
super(s);
}
/**
* Constructs a {@code NoAccessException} with the specified cause.
*
* @param cause the underlying cause of the exception
*/
public NoAccessException(Throwable cause) {
super(cause);
}
/**
* Constructs a {@code NoAccessException} with the specified
* detail message and cause.
*
* @param s the detail message
* @param cause the underlying cause of the exception
*/
public NoAccessException(String s, Throwable cause) {
super(s, cause);
}
}
......@@ -129,7 +129,7 @@ public class CallSiteImpl {
MethodType.methodType(void.class,
String.class, MethodType.class,
MemberName.class, int.class));
} catch (NoAccessException ex) {
} catch (ReflectiveOperationException ex) {
throw uncaughtException(ex);
}
}
......
......@@ -187,7 +187,7 @@ class FilterGeneric {
MethodHandle entryPoint = null;
try {
entryPoint = MethodHandleImpl.IMPL_LOOKUP.findSpecial(acls, iname, entryType, acls);
} catch (NoAccessException ex) {
} catch (ReflectiveOperationException ex) {
}
if (entryPoint == null) continue;
Constructor<? extends Adapter> ctor = null;
......
......@@ -56,7 +56,7 @@ public class FilterOneArgument extends BoundMethodHandle {
INVOKE =
MethodHandleImpl.IMPL_LOOKUP.findVirtual(FilterOneArgument.class, "invoke",
MethodType.genericMethodType(1));
} catch (NoAccessException ex) {
} catch (ReflectiveOperationException ex) {
throw uncaughtException(ex);
}
}
......
......@@ -204,7 +204,7 @@ class FromGeneric {
MethodHandle entryPoint = null;
try {
entryPoint = MethodHandleImpl.IMPL_LOOKUP.findSpecial(acls, iname, entryType, acls);
} catch (NoAccessException ex) {
} catch (ReflectiveOperationException ex) {
}
if (entryPoint == null) continue;
Constructor<? extends Adapter> ctor = null;
......
......@@ -44,7 +44,7 @@ class InvokeGeneric {
/** Compute and cache information for this adapter, so that it can
* call out to targets of the erasure-family of the given erased type.
*/
private InvokeGeneric(MethodType erasedCallerType) throws NoAccessException {
private InvokeGeneric(MethodType erasedCallerType) throws ReflectiveOperationException {
this.erasedCallerType = erasedCallerType;
this.initialInvoker = makeInitialInvoker();
assert initialInvoker.type().equals(erasedCallerType
......@@ -64,14 +64,14 @@ class InvokeGeneric {
try {
InvokeGeneric gen = new InvokeGeneric(form.erasedType());
form.genericInvoker = genericInvoker = gen.initialInvoker;
} catch (NoAccessException ex) {
} catch (ReflectiveOperationException ex) {
throw new RuntimeException(ex);
}
}
return genericInvoker;
}
private MethodHandle makeInitialInvoker() throws NoAccessException {
private MethodHandle makeInitialInvoker() throws ReflectiveOperationException {
// postDispatch = #(MH'; MT, MH; A...){MH'(MT, MH; A)}
MethodHandle postDispatch = makePostDispatchInvoker();
MethodHandle invoker;
......@@ -95,7 +95,7 @@ class InvokeGeneric {
return MethodHandles.dropArguments(targetInvoker, 1, EXTRA_ARGS);
}
private MethodHandle dispatcher(String dispatchName) throws NoAccessException {
private MethodHandle dispatcher(String dispatchName) throws ReflectiveOperationException {
return lookup().bind(this, dispatchName,
MethodType.methodType(MethodHandle.class,
MethodType.class, MethodHandle.class));
......
......@@ -69,7 +69,7 @@ public class Invokers {
if (invoker != null) return invoker;
try {
invoker = MethodHandleImpl.IMPL_LOOKUP.findVirtual(MethodHandle.class, "invokeExact", targetType);
} catch (NoAccessException ex) {
} catch (ReflectiveOperationException ex) {
throw new InternalError("JVM cannot find invoker for "+targetType);
}
assert(invokerType(targetType) == invoker.type());
......@@ -128,7 +128,7 @@ public class Invokers {
THROW_UCS = MethodHandleImpl.IMPL_LOOKUP
.findStatic(CallSite.class, "uninitializedCallSite",
MethodType.methodType(Empty.class));
} catch (NoAccessException ex) {
} catch (ReflectiveOperationException ex) {
throw new RuntimeException(ex);
}
}
......
/*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2011, 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
......@@ -451,8 +451,6 @@ public final class MemberName implements Member, Cloneable {
return type.toString(); // class java.lang.String
// else it is a field, method, or constructor
StringBuilder buf = new StringBuilder();
if (!isResolved())
buf.append("*.");
if (getDeclaringClass() != null) {
buf.append(getName(clazz));
buf.append('.');
......@@ -512,14 +510,24 @@ public final class MemberName implements Member, Cloneable {
public static RuntimeException newIllegalArgumentException(String message) {
return new IllegalArgumentException(message);
}
public static NoAccessException newNoAccessException(MemberName name, Class<?> lookupClass) {
return newNoAccessException("cannot access", name, lookupClass);
public static IllegalAccessException newNoAccessException(MemberName name, Object from) {
return newNoAccessException("cannot access", name, from);
}
public static NoAccessException newNoAccessException(String message,
MemberName name, Class<?> lookupClass) {
public static IllegalAccessException newNoAccessException(String message,
MemberName name, Object from) {
message += ": " + name;
if (lookupClass != null) message += ", from " + lookupClass.getName();
return new NoAccessException(message);
if (from != null) message += ", from " + from;
return new IllegalAccessException(message);
}
public static ReflectiveOperationException newNoAccessException(MemberName name) {
if (name.isResolved())
return new IllegalAccessException(name.toString());
else if (name.isConstructor())
return new NoSuchMethodException(name.toString());
else if (name.isMethod())
return new NoSuchMethodException(name.toString());
else
return new NoSuchFieldException(name.toString());
}
public static Error uncaughtException(Exception ex) {
Error err = new InternalError("uncaught exception");
......@@ -643,14 +651,20 @@ public final class MemberName implements Member, Cloneable {
/** Produce a resolved version of the given member.
* Super types are searched (for inherited members) if {@code searchSupers} is true.
* Access checking is performed on behalf of the given {@code lookupClass}.
* If lookup fails or access is not permitted, a {@linkplain NoAccessException} is thrown.
* If lookup fails or access is not permitted, a {@linkplain ReflectiveOperationException} is thrown.
* Otherwise a fresh copy of the given member is returned, with modifier bits filled in.
*/
public MemberName resolveOrFail(MemberName m, boolean searchSupers, Class<?> lookupClass) throws NoAccessException {
public
<NoSuchMemberException extends ReflectiveOperationException>
MemberName resolveOrFail(MemberName m, boolean searchSupers, Class<?> lookupClass,
Class<NoSuchMemberException> nsmClass)
throws IllegalAccessException, NoSuchMemberException {
MemberName result = resolveOrNull(m, searchSupers, lookupClass);
if (result != null)
return result;
throw newNoAccessException(m, lookupClass);
ReflectiveOperationException ex = newNoAccessException(m);
if (ex instanceof IllegalAccessException) throw (IllegalAccessException) ex;
throw nsmClass.cast(ex);
}
/** Return a list of all methods defined by the given class.
* Super types are searched (for inherited members) if {@code searchSupers} is true.
......
......@@ -30,7 +30,6 @@ import java.dyn.MethodHandles.Lookup;
import java.util.logging.Level;
import java.util.logging.Logger;
import sun.dyn.util.VerifyType;
import java.dyn.NoAccessException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
......@@ -169,11 +168,11 @@ public abstract class MethodHandleImpl {
* @param doDispatch whether the method handle will test the receiver type
* @param lookupClass access-check relative to this class
* @return a direct handle to the matching method
* @throws NoAccessException if the given method cannot be accessed by the lookup class
* @throws IllegalAccessException if the given method cannot be accessed by the lookup class
*/
public static
MethodHandle findMethod(Access token, MemberName method,
boolean doDispatch, Class<?> lookupClass) throws NoAccessException {
boolean doDispatch, Class<?> lookupClass) throws IllegalAccessException {
Access.check(token); // only trusted calls
MethodType mtype = method.getMethodType();
if (!method.isStatic()) {
......@@ -307,7 +306,7 @@ public abstract class MethodHandleImpl {
MethodHandle invoke = null;
try {
invoke = lookup.findVirtual(AllocateObject.class, name, MethodType.genericMethodType(nargs));
} catch (NoAccessException ex) {
} catch (ReflectiveOperationException ex) {
}
if (invoke == null) break;
invokes.add(invoke);
......@@ -322,7 +321,7 @@ public abstract class MethodHandleImpl {
static {
try {
VARARGS_INVOKE = IMPL_LOOKUP.findVirtual(AllocateObject.class, "invoke_V", MethodType.genericMethodType(0, true));
} catch (NoAccessException ex) {
} catch (ReflectiveOperationException ex) {
throw uncaughtException(ex);
}
}
......@@ -474,7 +473,7 @@ public abstract class MethodHandleImpl {
MethodHandle mh;
try {
mh = IMPL_LOOKUP.findVirtual(FieldAccessor.class, name, type);
} catch (NoAccessException ex) {
} catch (ReflectiveOperationException ex) {
throw uncaughtException(ex);
}
if (evclass != vclass || (!isStatic && ecclass != cclass)) {
......@@ -542,7 +541,7 @@ public abstract class MethodHandleImpl {
MethodHandle mh;
try {
mh = IMPL_LOOKUP.findStatic(FieldAccessor.class, name, type);
} catch (NoAccessException ex) {
} catch (ReflectiveOperationException ex) {
throw uncaughtException(ex);
}
if (caclass != null) {
......@@ -1014,7 +1013,7 @@ public abstract class MethodHandleImpl {
MethodHandle invoke = null;
try {
invoke = lookup.findVirtual(GuardWithTest.class, name, MethodType.genericMethodType(nargs));
} catch (NoAccessException ex) {
} catch (ReflectiveOperationException ex) {
}
if (invoke == null) break;
invokes.add(invoke);
......@@ -1029,7 +1028,7 @@ public abstract class MethodHandleImpl {
static {
try {
VARARGS_INVOKE = IMPL_LOOKUP.findVirtual(GuardWithTest.class, "invoke_V", MethodType.genericMethodType(0, true));
} catch (NoAccessException ex) {
} catch (ReflectiveOperationException ex) {
throw uncaughtException(ex);
}
}
......@@ -1150,7 +1149,7 @@ public abstract class MethodHandleImpl {
MethodHandle invoke = null;
try {
invoke = lookup.findVirtual(GuardWithCatch.class, name, MethodType.genericMethodType(nargs));
} catch (NoAccessException ex) {
} catch (ReflectiveOperationException ex) {
}
if (invoke == null) break;
invokes.add(invoke);
......@@ -1165,7 +1164,7 @@ public abstract class MethodHandleImpl {
static {
try {
VARARGS_INVOKE = IMPL_LOOKUP.findVirtual(GuardWithCatch.class, "invoke_V", MethodType.genericMethodType(0, true));
} catch (NoAccessException ex) {
} catch (ReflectiveOperationException ex) {
throw uncaughtException(ex);
}
}
......@@ -1212,7 +1211,7 @@ public abstract class MethodHandleImpl {
THROW_EXCEPTION
= IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "throwException",
MethodType.methodType(Empty.class, Throwable.class));
} catch (NoAccessException ex) {
} catch (ReflectiveOperationException ex) {
throw new RuntimeException(ex);
}
}
......
......@@ -350,7 +350,7 @@ class MethodHandleNatives {
case REF_invokeInterface: return lookup.findVirtual( defc, name, (MethodType) type );
}
throw new IllegalArgumentException("bad MethodHandle constant "+name+" : "+type);
} catch (NoAccessException ex) {
} catch (ReflectiveOperationException ex) {
Error err = new IncompatibleClassChangeError();
err.initCause(ex);
throw err;
......
......@@ -167,7 +167,7 @@ class SpreadGeneric {
MethodHandle entryPoint = null;
try {
entryPoint = MethodHandleImpl.IMPL_LOOKUP.findSpecial(acls, iname, entryType, acls);
} catch (NoAccessException ex) {
} catch (ReflectiveOperationException ex) {
}
if (entryPoint == null) continue;
Constructor<? extends Adapter> ctor = null;
......
......@@ -285,7 +285,7 @@ class ToGeneric {
try {
entryPoint = MethodHandleImpl.IMPL_LOOKUP.
findSpecial(acls, iname, entryPointType, acls);
} catch (NoAccessException ex) {
} catch (ReflectiveOperationException ex) {
}
if (entryPoint == null) continue;
Constructor<? extends Adapter> ctor = null;
......
......@@ -153,7 +153,7 @@ public class ValueConversions {
try {
// actually, type is wrong; the Java method takes Object
mh = IMPL_LOOKUP.findStatic(ValueConversions.class, name, type.erase());
} catch (NoAccessException ex) {
} catch (ReflectiveOperationException ex) {
mh = null;
}
} else {
......@@ -289,7 +289,7 @@ public class ValueConversions {
if (exact) {
try {
mh = IMPL_LOOKUP.findStatic(ValueConversions.class, name, type);
} catch (NoAccessException ex) {
} catch (ReflectiveOperationException ex) {
mh = null;
}
} else {
......@@ -408,7 +408,7 @@ public class ValueConversions {
if (exact) {
try {
mh = IMPL_LOOKUP.findStatic(ValueConversions.class, name, type);
} catch (NoAccessException ex) {
} catch (ReflectiveOperationException ex) {
mh = null;
}
} else {
......@@ -492,7 +492,7 @@ public class ValueConversions {
case INT: case LONG: case FLOAT: case DOUBLE:
try {
mh = IMPL_LOOKUP.findStatic(ValueConversions.class, "zero"+wrap.simpleName(), type);
} catch (NoAccessException ex) {
} catch (ReflectiveOperationException ex) {
mh = null;
}
break;
......@@ -654,7 +654,7 @@ public class ValueConversions {
type = type.appendParameterTypes(wrap.primitiveType());
try {
mh = IMPL_LOOKUP.findStatic(ValueConversions.class, "identity", type);
} catch (NoAccessException ex) {
} catch (ReflectiveOperationException ex) {
mh = null;
}
if (mh == null && wrap == Wrapper.VOID) {
......@@ -723,7 +723,7 @@ public class ValueConversions {
MethodHandle array = null;
try {
array = lookup.findStatic(ValueConversions.class, name, type);
} catch (NoAccessException ex) {
} catch (ReflectiveOperationException ex) {
}
if (array == null) break;
arrays.add(array);
......@@ -784,7 +784,7 @@ public class ValueConversions {
MethodHandle array = null;
try {
array = lookup.findStatic(ValueConversions.class, name, type);
} catch (NoAccessException ex) {
} catch (ReflectiveOperationException ex) {
}
if (array == null) break;
arrays.add(array);
......
......@@ -25,7 +25,6 @@
package sun.dyn.util;
import java.dyn.NoAccessException;
import java.lang.reflect.Modifier;
import sun.dyn.MemberName;
import sun.dyn.MethodHandleImpl;
......@@ -139,6 +138,8 @@ public class VerifyAccess {
* <li>C is public.
* <li>C and D are members of the same runtime package.
* </ul>
* @param refc the symbolic reference class to which access is being checked (C)
* @param lookupClass the class performing the lookup (D)
*/
public static boolean isClassAccessible(Class<?> refc, Class<?> lookupClass) {
int mods = refc.getModifiers();
......
......@@ -338,7 +338,7 @@ public class InvokeGenericTest {
= LOOKUP.findStatic(LOOKUP.lookupClass(),
"collector",
methodType(Object.class, Object[].class));
} catch (NoAccessException ex) {
} catch (ReflectiveOperationException ex) {
throw new RuntimeException(ex);
}
}
......
......@@ -74,7 +74,7 @@ static final private Lookup LOOKUP = lookup();
// static final private MethodHandle HASHCODE_1 = LOOKUP.findVirtual(Object.class,
// "hashCode", methodType(int.class));
// form required if NoAccessException is intercepted:
// form required if ReflectiveOperationException is intercepted:
static final private MethodHandle CONCAT_2, HASHCODE_2;
static {
try {
......@@ -82,7 +82,7 @@ static {
"concat", methodType(String.class, String.class));
HASHCODE_2 = LOOKUP.findVirtual(Object.class,
"hashCode", methodType(int.class));
} catch (NoAccessException ex) {
} catch (ReflectiveOperationException ex) {
throw new RuntimeException(ex);
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册