8001108: an attempt to use "<init>" as a method name should elicit NoSuchMethodException
Add an explicit check for leading "<", upgrade the unit tests Reviewed-by: twisti, darcy
This commit is contained in:
parent
e4df9dc1ee
commit
154969a2bc
@ -289,6 +289,9 @@ public class MethodHandles {
|
||||
* In general, the conditions under which a method handle may be
|
||||
* looked up for a method {@code M} are exactly equivalent to the conditions
|
||||
* under which the lookup class could have compiled and resolved a call to {@code M}.
|
||||
* Where the JVM would raise exceptions like {@code NoSuchMethodError},
|
||||
* a method handle lookup will generally raise a corresponding
|
||||
* checked exception, such as {@code NoSuchMethodException}.
|
||||
* And the effect of invoking the method handle resulting from the lookup
|
||||
* is exactly equivalent to executing the compiled and resolved call to {@code M}.
|
||||
* The same point is true of fields and constructors.
|
||||
@ -305,6 +308,12 @@ public class MethodHandles {
|
||||
* (which will necessarily be a superclass of the lookup class)
|
||||
* to the lookup class itself.
|
||||
* <p>
|
||||
* The JVM represents constructors and static initializer blocks as internal methods
|
||||
* with special names ({@code "<init>"} and {@code "<clinit>"}).
|
||||
* The internal syntax of invocation instructions allows them to refer to such internal
|
||||
* methods as if they were normal methods, but the JVM bytecode verifier rejects them.
|
||||
* A lookup of such an internal method will produce a {@code NoSuchMethodException}.
|
||||
* <p>
|
||||
* In some cases, access between nested classes is obtained by the Java compiler by creating
|
||||
* an wrapper method to access a private method of another class
|
||||
* in the same top-level declaration.
|
||||
@ -604,6 +613,15 @@ public class MethodHandles {
|
||||
* The returned method handle will have
|
||||
* {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
|
||||
* the method's variable arity modifier bit ({@code 0x0080}) is set.
|
||||
* <b>Example:</b>
|
||||
* <p><blockquote><pre>{@code
|
||||
import static java.lang.invoke.MethodHandles.*;
|
||||
import static java.lang.invoke.MethodType.*;
|
||||
...
|
||||
MethodHandle MH_asList = publicLookup().findStatic(Arrays.class,
|
||||
"asList", methodType(List.class, Object[].class));
|
||||
assertEquals("[x, y]", MH_asList.invoke("x", "y").toString());
|
||||
* }</pre></blockquote>
|
||||
* @param refc the class from which the method is accessed
|
||||
* @param name the name of the method
|
||||
* @param type the type of the method
|
||||
@ -654,6 +672,34 @@ public class MethodHandles {
|
||||
* {@link java.lang.invoke.MethodHandles#invoker MethodHandles.invoker}
|
||||
* with the same {@code type} argument.
|
||||
*
|
||||
* <b>Example:</b>
|
||||
* <p><blockquote><pre>{@code
|
||||
import static java.lang.invoke.MethodHandles.*;
|
||||
import static java.lang.invoke.MethodType.*;
|
||||
...
|
||||
MethodHandle MH_concat = publicLookup().findVirtual(String.class,
|
||||
"concat", methodType(String.class, String.class));
|
||||
MethodHandle MH_hashCode = publicLookup().findVirtual(Object.class,
|
||||
"hashCode", methodType(int.class));
|
||||
MethodHandle MH_hashCode_String = publicLookup().findVirtual(String.class,
|
||||
"hashCode", methodType(int.class));
|
||||
assertEquals("xy", (String) MH_concat.invokeExact("x", "y"));
|
||||
assertEquals("xy".hashCode(), (int) MH_hashCode.invokeExact((Object)"xy"));
|
||||
assertEquals("xy".hashCode(), (int) MH_hashCode_String.invokeExact("xy"));
|
||||
// interface method:
|
||||
MethodHandle MH_subSequence = publicLookup().findVirtual(CharSequence.class,
|
||||
"subSequence", methodType(CharSequence.class, int.class, int.class));
|
||||
assertEquals("def", MH_subSequence.invoke("abcdefghi", 3, 6).toString());
|
||||
// constructor "internal method" must be accessed differently:
|
||||
MethodType MT_newString = methodType(void.class); //()V for new String()
|
||||
try { assertEquals("impossible", lookup()
|
||||
.findVirtual(String.class, "<init>", MT_newString));
|
||||
} catch (NoSuchMethodException ex) { } // OK
|
||||
MethodHandle MH_newString = publicLookup()
|
||||
.findConstructor(String.class, MT_newString);
|
||||
assertEquals("", (String) MH_newString.invokeExact());
|
||||
* }</pre></blockquote>
|
||||
*
|
||||
* @param refc the class or interface from which the method is accessed
|
||||
* @param name the name of the method
|
||||
* @param type the type of the method, with the receiver argument omitted
|
||||
@ -696,12 +742,30 @@ public class MethodHandles {
|
||||
* If the constructor's class has not yet been initialized, that is done
|
||||
* immediately, before the method handle is returned.
|
||||
* <p>
|
||||
* Note: The requested type must have a return type of {@code void}.
|
||||
* This is consistent with the JVM's treatment of constructor type descriptors.
|
||||
* <em>(Note: The requested type must have a return type of {@code void}.
|
||||
* This is consistent with the JVM's treatment of constructor type descriptors.)</em>
|
||||
* <p>
|
||||
* The returned method handle will have
|
||||
* {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
|
||||
* the constructor's variable arity modifier bit ({@code 0x0080}) is set.
|
||||
* <p><b>Example:</b>
|
||||
* <p><blockquote><pre>{@code
|
||||
import static java.lang.invoke.MethodHandles.*;
|
||||
import static java.lang.invoke.MethodType.*;
|
||||
...
|
||||
MethodHandle MH_newArrayList = publicLookup().findConstructor(
|
||||
ArrayList.class, methodType(void.class, Collection.class));
|
||||
Collection orig = Arrays.asList("x", "y");
|
||||
Collection copy = (ArrayList) MH_newArrayList.invokeExact(orig);
|
||||
assert(orig != copy);
|
||||
assertEquals(orig, copy);
|
||||
// a variable-arity constructor:
|
||||
MethodHandle MH_newProcessBuilder = publicLookup().findConstructor(
|
||||
ProcessBuilder.class, methodType(void.class, String[].class));
|
||||
ProcessBuilder pb = (ProcessBuilder)
|
||||
MH_newProcessBuilder.invoke("x", "y", "z");
|
||||
assertEquals("[x, y, z]", pb.command().toString());
|
||||
* }</pre></blockquote>
|
||||
* @param refc the class or interface from which the method is accessed
|
||||
* @param type the type of the method, with the receiver argument omitted, and a void return type
|
||||
* @return the desired method handle
|
||||
@ -741,6 +805,45 @@ public class MethodHandles {
|
||||
* The returned method handle will have
|
||||
* {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
|
||||
* the method's variable arity modifier bit ({@code 0x0080}) is set.
|
||||
* <p>
|
||||
* <em>(Note: JVM internal methods named {@code "<init>"} are not visible to this API,
|
||||
* even though the {@code invokespecial} instruction can refer to them
|
||||
* in special circumstances. Use {@link #findConstructor findConstructor}
|
||||
* to access instance initialization methods in a safe manner.)</em>
|
||||
* <p><b>Example:</b>
|
||||
* <p><blockquote><pre>{@code
|
||||
import static java.lang.invoke.MethodHandles.*;
|
||||
import static java.lang.invoke.MethodType.*;
|
||||
...
|
||||
static class Listie extends ArrayList {
|
||||
public String toString() { return "[wee Listie]"; }
|
||||
static Lookup lookup() { return MethodHandles.lookup(); }
|
||||
}
|
||||
...
|
||||
// no access to constructor via invokeSpecial:
|
||||
MethodHandle MH_newListie = Listie.lookup()
|
||||
.findConstructor(Listie.class, methodType(void.class));
|
||||
Listie l = (Listie) MH_newListie.invokeExact();
|
||||
try { assertEquals("impossible", Listie.lookup().findSpecial(
|
||||
Listie.class, "<init>", methodType(void.class), Listie.class));
|
||||
} catch (NoSuchMethodException ex) { } // OK
|
||||
// access to super and self methods via invokeSpecial:
|
||||
MethodHandle MH_super = Listie.lookup().findSpecial(
|
||||
ArrayList.class, "toString" , methodType(String.class), Listie.class);
|
||||
MethodHandle MH_this = Listie.lookup().findSpecial(
|
||||
Listie.class, "toString" , methodType(String.class), Listie.class);
|
||||
MethodHandle MH_duper = Listie.lookup().findSpecial(
|
||||
Object.class, "toString" , methodType(String.class), Listie.class);
|
||||
assertEquals("[]", (String) MH_super.invokeExact(l));
|
||||
assertEquals(""+l, (String) MH_this.invokeExact(l));
|
||||
assertEquals("[]", (String) MH_duper.invokeExact(l)); // ArrayList method
|
||||
try { assertEquals("inaccessible", Listie.lookup().findSpecial(
|
||||
String.class, "toString", methodType(String.class), Listie.class));
|
||||
} catch (IllegalAccessException ex) { } // OK
|
||||
Listie subl = new Listie() { public String toString() { return "[subclass]"; } };
|
||||
assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method
|
||||
* }</pre></blockquote>
|
||||
*
|
||||
* @param refc the class or interface from which the method is accessed
|
||||
* @param name the name of the method (which must not be "<init>")
|
||||
* @param type the type of the method, with the receiver argument omitted
|
||||
@ -1105,6 +1208,7 @@ return mh1;
|
||||
checkSymbolicClass(refc); // do this before attempting to resolve
|
||||
name.getClass(); // NPE
|
||||
type.getClass(); // NPE
|
||||
checkMethodName(refKind, name); // NPE check on name
|
||||
return IMPL_NAMES.resolveOrFail(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(),
|
||||
NoSuchMethodException.class);
|
||||
}
|
||||
@ -1124,6 +1228,13 @@ return mh1;
|
||||
throw new MemberName(refc).makeAccessException("symbolic reference class is not public", this);
|
||||
}
|
||||
|
||||
/** Check name for an illegal leading "<" character. */
|
||||
void checkMethodName(byte refKind, String name) throws NoSuchMethodException {
|
||||
if (name.startsWith("<") && refKind != REF_newInvokeSpecial)
|
||||
throw new NoSuchMethodException("illegal method name: "+name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find my trustable caller class if m is a caller sensitive method.
|
||||
* If this lookup object has private access, then the caller class is the lookupClass.
|
||||
|
@ -53,7 +53,11 @@ public class JavaDocExamplesTest {
|
||||
}
|
||||
|
||||
public void run() throws Throwable {
|
||||
testMisc();
|
||||
testFindStatic();
|
||||
testFindConstructor();
|
||||
testFindVirtual();
|
||||
testFindSpecial();
|
||||
testPermuteArguments();
|
||||
testDropArguments();
|
||||
testFilterArguments();
|
||||
@ -99,7 +103,8 @@ static {
|
||||
|
||||
{}
|
||||
|
||||
@Test public void testFindVirtual() throws Throwable {
|
||||
@Test public void testMisc() throws Throwable {
|
||||
// Extra tests, not from javadoc:
|
||||
{}
|
||||
MethodHandle CONCAT_3 = LOOKUP.findVirtual(String.class,
|
||||
"concat", methodType(String.class, String.class));
|
||||
@ -114,6 +119,92 @@ assertEquals("xy".hashCode(), (int) HASHCODE_3.invokeExact((Object)"xy"));
|
||||
{}
|
||||
}
|
||||
|
||||
@Test public void testFindStatic() throws Throwable {
|
||||
{}
|
||||
MethodHandle MH_asList = publicLookup().findStatic(Arrays.class,
|
||||
"asList", methodType(List.class, Object[].class));
|
||||
assertEquals("[x, y]", MH_asList.invoke("x", "y").toString());
|
||||
{}
|
||||
}
|
||||
|
||||
@Test public void testFindVirtual() throws Throwable {
|
||||
{}
|
||||
MethodHandle MH_concat = publicLookup().findVirtual(String.class,
|
||||
"concat", methodType(String.class, String.class));
|
||||
MethodHandle MH_hashCode = publicLookup().findVirtual(Object.class,
|
||||
"hashCode", methodType(int.class));
|
||||
MethodHandle MH_hashCode_String = publicLookup().findVirtual(String.class,
|
||||
"hashCode", methodType(int.class));
|
||||
assertEquals("xy", (String) MH_concat.invokeExact("x", "y"));
|
||||
assertEquals("xy".hashCode(), (int) MH_hashCode.invokeExact((Object)"xy"));
|
||||
assertEquals("xy".hashCode(), (int) MH_hashCode_String.invokeExact("xy"));
|
||||
// interface method:
|
||||
MethodHandle MH_subSequence = publicLookup().findVirtual(CharSequence.class,
|
||||
"subSequence", methodType(CharSequence.class, int.class, int.class));
|
||||
assertEquals("def", MH_subSequence.invoke("abcdefghi", 3, 6).toString());
|
||||
// constructor "internal method" must be accessed differently:
|
||||
MethodType MT_newString = methodType(void.class); //()V for new String()
|
||||
try { assertEquals("impossible", lookup()
|
||||
.findVirtual(String.class, "<init>", MT_newString));
|
||||
} catch (NoSuchMethodException ex) { } // OK
|
||||
MethodHandle MH_newString = publicLookup()
|
||||
.findConstructor(String.class, MT_newString);
|
||||
assertEquals("", (String) MH_newString.invokeExact());
|
||||
{}
|
||||
}
|
||||
|
||||
@Test public void testFindConstructor() throws Throwable {
|
||||
{}
|
||||
MethodHandle MH_newArrayList = publicLookup().findConstructor(
|
||||
ArrayList.class, methodType(void.class, Collection.class));
|
||||
Collection orig = Arrays.asList("x", "y");
|
||||
Collection copy = (ArrayList) MH_newArrayList.invokeExact(orig);
|
||||
assert(orig != copy);
|
||||
assertEquals(orig, copy);
|
||||
// a variable-arity constructor:
|
||||
MethodHandle MH_newProcessBuilder = publicLookup().findConstructor(
|
||||
ProcessBuilder.class, methodType(void.class, String[].class));
|
||||
ProcessBuilder pb = (ProcessBuilder)
|
||||
MH_newProcessBuilder.invoke("x", "y", "z");
|
||||
assertEquals("[x, y, z]", pb.command().toString());
|
||||
{}
|
||||
}
|
||||
|
||||
// for testFindSpecial
|
||||
{}
|
||||
static class Listie extends ArrayList {
|
||||
public String toString() { return "[wee Listie]"; }
|
||||
static Lookup lookup() { return MethodHandles.lookup(); }
|
||||
}
|
||||
{}
|
||||
|
||||
@Test public void testFindSpecial() throws Throwable {
|
||||
{}
|
||||
// no access to constructor via invokeSpecial:
|
||||
MethodHandle MH_newListie = Listie.lookup()
|
||||
.findConstructor(Listie.class, methodType(void.class));
|
||||
Listie l = (Listie) MH_newListie.invokeExact();
|
||||
try { assertEquals("impossible", Listie.lookup().findSpecial(
|
||||
Listie.class, "<init>", methodType(void.class), Listie.class));
|
||||
} catch (NoSuchMethodException ex) { } // OK
|
||||
// access to super and self methods via invokeSpecial:
|
||||
MethodHandle MH_super = Listie.lookup().findSpecial(
|
||||
ArrayList.class, "toString" , methodType(String.class), Listie.class);
|
||||
MethodHandle MH_this = Listie.lookup().findSpecial(
|
||||
Listie.class, "toString" , methodType(String.class), Listie.class);
|
||||
MethodHandle MH_duper = Listie.lookup().findSpecial(
|
||||
Object.class, "toString" , methodType(String.class), Listie.class);
|
||||
assertEquals("[]", (String) MH_super.invokeExact(l));
|
||||
assertEquals(""+l, (String) MH_this.invokeExact(l));
|
||||
assertEquals("[]", (String) MH_duper.invokeExact(l)); // ArrayList method
|
||||
try { assertEquals("inaccessible", Listie.lookup().findSpecial(
|
||||
String.class, "toString", methodType(String.class), Listie.class));
|
||||
} catch (IllegalAccessException ex) { } // OK
|
||||
Listie subl = new Listie() { public String toString() { return "[subclass]"; } };
|
||||
assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method
|
||||
{}
|
||||
}
|
||||
|
||||
@Test public void testPermuteArguments() throws Throwable {
|
||||
{{
|
||||
{} /// JAVADOC
|
||||
|
@ -387,6 +387,7 @@ public class MethodHandlesTest {
|
||||
protected Example(String name) { this.name = name; }
|
||||
@SuppressWarnings("LeakingThisInConstructor")
|
||||
protected Example(int x) { this(); called("protected <init>", this, x); }
|
||||
//Example(Void x) { does not exist; lookup elicts NoSuchMethodException }
|
||||
@Override public String toString() { return name; }
|
||||
|
||||
public void v0() { called("v0", this); }
|
||||
@ -487,6 +488,9 @@ public class MethodHandlesTest {
|
||||
return lookup.in(defc);
|
||||
}
|
||||
|
||||
/** Is findVirtual (etc.) of "<init>" supposed to elicit a NoSuchMethodException? */
|
||||
final static boolean INIT_REF_CAUSES_NSME = true;
|
||||
|
||||
@Test
|
||||
public void testFindStatic() throws Throwable {
|
||||
if (CAN_SKIP_WORKING) return;
|
||||
@ -507,6 +511,8 @@ public class MethodHandlesTest {
|
||||
testFindStatic(Example.class, Object.class, "s7", float.class, double.class);
|
||||
|
||||
testFindStatic(false, PRIVATE, Example.class, void.class, "bogus");
|
||||
testFindStatic(false, PRIVATE, Example.class, void.class, "<init>", int.class);
|
||||
testFindStatic(false, PRIVATE, Example.class, void.class, "<init>", Void.class);
|
||||
testFindStatic(false, PRIVATE, Example.class, void.class, "v0");
|
||||
}
|
||||
|
||||
@ -529,11 +535,12 @@ public class MethodHandlesTest {
|
||||
target = maybeMoveIn(lookup, defc).findStatic(defc, methodName, type);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
noAccess = ex;
|
||||
assertExceptionClass(
|
||||
(name.contains("bogus") || INIT_REF_CAUSES_NSME && name.contains("<init>"))
|
||||
? NoSuchMethodException.class
|
||||
: IllegalAccessException.class,
|
||||
noAccess);
|
||||
if (verbosity >= 5) ex.printStackTrace(System.out);
|
||||
if (name.contains("bogus"))
|
||||
assertTrue(noAccess instanceof NoSuchMethodException);
|
||||
else
|
||||
assertTrue(noAccess instanceof IllegalAccessException);
|
||||
}
|
||||
if (verbosity >= 3)
|
||||
System.out.println("findStatic "+lookup+": "+defc.getName()+"."+name+"/"+type+" => "+target
|
||||
@ -551,6 +558,13 @@ public class MethodHandlesTest {
|
||||
System.out.print(':');
|
||||
}
|
||||
|
||||
static void assertExceptionClass(Class<? extends Throwable> expected,
|
||||
Throwable actual) {
|
||||
if (expected.isInstance(actual)) return;
|
||||
actual.printStackTrace();
|
||||
assertEquals(expected, actual.getClass());
|
||||
}
|
||||
|
||||
static final boolean DEBUG_METHOD_HANDLE_NAMES = Boolean.getBoolean("java.lang.invoke.MethodHandle.DEBUG_NAMES");
|
||||
|
||||
// rough check of name string
|
||||
@ -580,6 +594,8 @@ public class MethodHandlesTest {
|
||||
testFindVirtual(PubExample.class, void.class, "Pub/pro_v0");
|
||||
|
||||
testFindVirtual(false, PRIVATE, Example.class, Example.class, void.class, "bogus");
|
||||
testFindVirtual(false, PRIVATE, Example.class, Example.class, void.class, "<init>", int.class);
|
||||
testFindVirtual(false, PRIVATE, Example.class, Example.class, void.class, "<init>", Void.class);
|
||||
testFindVirtual(false, PRIVATE, Example.class, Example.class, void.class, "s0");
|
||||
|
||||
// test dispatch
|
||||
@ -628,11 +644,12 @@ public class MethodHandlesTest {
|
||||
target = maybeMoveIn(lookup, defc).findVirtual(defc, methodName, type);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
noAccess = ex;
|
||||
assertExceptionClass(
|
||||
(name.contains("bogus") || INIT_REF_CAUSES_NSME && name.contains("<init>"))
|
||||
? NoSuchMethodException.class
|
||||
: IllegalAccessException.class,
|
||||
noAccess);
|
||||
if (verbosity >= 5) ex.printStackTrace(System.out);
|
||||
if (name.contains("bogus"))
|
||||
assertTrue(noAccess instanceof NoSuchMethodException);
|
||||
else
|
||||
assertTrue(noAccess instanceof IllegalAccessException);
|
||||
}
|
||||
if (verbosity >= 3)
|
||||
System.out.println("findVirtual "+lookup+": "+defc.getName()+"."+name+"/"+type+" => "+target
|
||||
@ -682,11 +699,11 @@ public class MethodHandlesTest {
|
||||
testFindSpecial(SubExample.class, Example.class, void.class, "pkg_v0");
|
||||
testFindSpecial(RemoteExample.class, PubExample.class, void.class, "Pub/pro_v0");
|
||||
// Do some negative testing:
|
||||
testFindSpecial(false, EXAMPLE, SubExample.class, Example.class, void.class, "bogus");
|
||||
testFindSpecial(false, PRIVATE, SubExample.class, Example.class, void.class, "bogus");
|
||||
for (Lookup lookup : new Lookup[]{ PRIVATE, EXAMPLE, PACKAGE, PUBLIC }) {
|
||||
testFindSpecial(false, lookup, Object.class, Example.class, void.class, "v0");
|
||||
testFindSpecial(false, lookup, SubExample.class, Example.class, void.class, "bogus");
|
||||
testFindSpecial(false, lookup, SubExample.class, Example.class, void.class, "<init>", int.class);
|
||||
testFindSpecial(false, lookup, SubExample.class, Example.class, void.class, "<init>", Void.class);
|
||||
testFindSpecial(false, lookup, SubExample.class, Example.class, void.class, "s0");
|
||||
}
|
||||
}
|
||||
@ -712,19 +729,25 @@ public class MethodHandlesTest {
|
||||
countTest(positive);
|
||||
String methodName = name.substring(1 + name.indexOf('/')); // foo/bar => foo
|
||||
MethodType type = MethodType.methodType(ret, params);
|
||||
Lookup specialLookup = maybeMoveIn(lookup, specialCaller);
|
||||
boolean specialAccessOK = (specialLookup.lookupClass() == specialCaller &&
|
||||
(specialLookup.lookupModes() & Lookup.PRIVATE) != 0);
|
||||
MethodHandle target = null;
|
||||
Exception noAccess = null;
|
||||
try {
|
||||
if (verbosity >= 4) System.out.println("lookup via "+lookup+" of "+defc+" "+name+type);
|
||||
if (verbosity >= 5) System.out.println(" lookup => "+maybeMoveIn(lookup, specialCaller));
|
||||
target = maybeMoveIn(lookup, specialCaller).findSpecial(defc, methodName, type, specialCaller);
|
||||
if (verbosity >= 5) System.out.println(" lookup => "+specialLookup);
|
||||
target = specialLookup.findSpecial(defc, methodName, type, specialCaller);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
noAccess = ex;
|
||||
assertExceptionClass(
|
||||
(!specialAccessOK) // this check should happen first
|
||||
? IllegalAccessException.class
|
||||
: (name.contains("bogus") || INIT_REF_CAUSES_NSME && name.contains("<init>"))
|
||||
? NoSuchMethodException.class
|
||||
: IllegalAccessException.class,
|
||||
noAccess);
|
||||
if (verbosity >= 5) ex.printStackTrace(System.out);
|
||||
if (name.contains("bogus"))
|
||||
assertTrue(noAccess instanceof NoSuchMethodException);
|
||||
else
|
||||
assertTrue(noAccess instanceof IllegalAccessException);
|
||||
}
|
||||
if (verbosity >= 3)
|
||||
System.out.println("findSpecial from "+specialCaller.getName()+" to "+defc.getName()+"."+name+"/"+type+" => "+target
|
||||
@ -769,7 +792,7 @@ public class MethodHandlesTest {
|
||||
target = lookup.findConstructor(defc, type);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
noAccess = ex;
|
||||
assertTrue(noAccess instanceof IllegalAccessException);
|
||||
assertTrue(noAccess.getClass().getName(), noAccess instanceof IllegalAccessException);
|
||||
}
|
||||
if (verbosity >= 3)
|
||||
System.out.println("findConstructor "+defc.getName()+".<init>/"+type+" => "+target
|
||||
@ -800,6 +823,8 @@ public class MethodHandlesTest {
|
||||
testBind(Example.class, Object.class, "v2", int.class, Object.class);
|
||||
testBind(Example.class, Object.class, "v2", int.class, int.class);
|
||||
testBind(false, PRIVATE, Example.class, void.class, "bogus");
|
||||
testBind(false, PRIVATE, Example.class, void.class, "<init>", int.class);
|
||||
testBind(false, PRIVATE, Example.class, void.class, "<init>", Void.class);
|
||||
testBind(SubExample.class, void.class, "Sub/v0");
|
||||
testBind(SubExample.class, void.class, "Sub/pkg_v0");
|
||||
testBind(IntExample.Impl.class, void.class, "Int/v0");
|
||||
@ -823,11 +848,12 @@ public class MethodHandlesTest {
|
||||
target = maybeMoveIn(lookup, defc).bind(receiver, methodName, type);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
noAccess = ex;
|
||||
assertExceptionClass(
|
||||
(name.contains("bogus") || INIT_REF_CAUSES_NSME && name.contains("<init>"))
|
||||
? NoSuchMethodException.class
|
||||
: IllegalAccessException.class,
|
||||
noAccess);
|
||||
if (verbosity >= 5) ex.printStackTrace(System.out);
|
||||
if (name.contains("bogus"))
|
||||
assertTrue(noAccess instanceof NoSuchMethodException);
|
||||
else
|
||||
assertTrue(noAccess instanceof IllegalAccessException);
|
||||
}
|
||||
if (verbosity >= 3)
|
||||
System.out.println("bind "+receiver+"."+name+"/"+type+" => "+target
|
||||
@ -890,6 +916,10 @@ public class MethodHandlesTest {
|
||||
countTest(positive);
|
||||
String methodName = name.substring(1 + name.indexOf('/')); // foo/bar => foo
|
||||
MethodType type = MethodType.methodType(ret, params);
|
||||
Lookup specialLookup = (specialCaller != null ? maybeMoveIn(lookup, specialCaller) : null);
|
||||
boolean specialAccessOK = (specialCaller != null &&
|
||||
specialLookup.lookupClass() == specialCaller &&
|
||||
(specialLookup.lookupModes() & Lookup.PRIVATE) != 0);
|
||||
Method rmethod = defc.getDeclaredMethod(methodName, params);
|
||||
MethodHandle target = null;
|
||||
Exception noAccess = null;
|
||||
@ -898,16 +928,15 @@ public class MethodHandlesTest {
|
||||
try {
|
||||
if (verbosity >= 4) System.out.println("lookup via "+lookup+" of "+defc+" "+name+type);
|
||||
if (isSpecial)
|
||||
target = maybeMoveIn(lookup, specialCaller).unreflectSpecial(rmethod, specialCaller);
|
||||
target = specialLookup.unreflectSpecial(rmethod, specialCaller);
|
||||
else
|
||||
target = maybeMoveIn(lookup, defc).unreflect(rmethod);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
noAccess = ex;
|
||||
assertExceptionClass(
|
||||
IllegalAccessException.class, // NSME is impossible, since it was already reflected
|
||||
noAccess);
|
||||
if (verbosity >= 5) ex.printStackTrace(System.out);
|
||||
if (name.contains("bogus"))
|
||||
assertTrue(noAccess instanceof NoSuchMethodException);
|
||||
else
|
||||
assertTrue(noAccess instanceof IllegalAccessException);
|
||||
}
|
||||
if (verbosity >= 3)
|
||||
System.out.println("unreflect"+(isSpecial?"Special":"")+" "+defc.getName()+"."+name+"/"+type
|
||||
@ -1141,11 +1170,12 @@ public class MethodHandlesTest {
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
mh = null;
|
||||
noAccess = ex;
|
||||
assertExceptionClass(
|
||||
(fname.contains("bogus"))
|
||||
? NoSuchFieldException.class
|
||||
: IllegalAccessException.class,
|
||||
noAccess);
|
||||
if (verbosity >= 5) ex.printStackTrace(System.out);
|
||||
if (fname.contains("bogus"))
|
||||
assertTrue(noAccess instanceof NoSuchFieldException);
|
||||
else
|
||||
assertTrue(noAccess instanceof IllegalAccessException);
|
||||
}
|
||||
if (verbosity >= 3)
|
||||
System.out.println("find"+(isStatic?"Static":"")+(isGetter?"Getter":"Setter")+" "+fclass.getName()+"."+fname+"/"+ftype
|
||||
|
Loading…
x
Reference in New Issue
Block a user