fix exception wrapping for Method.invoke and static initializers

Method.invoke should initialize its class before invoking the method,
throwing an ExceptionInInitializerError if it fails, without wrapping
said error in an InvocationTargetException.

Also, we must initialize ExceptionInInitializerError.exception when
throwing instances from the VM, since OpenJDK's
ExceptionInInitializerError.getCause uses the exception field, not the
cause field.
This commit is contained in:
Joel Dice
2013-12-05 22:28:13 -07:00
parent 451fe159c2
commit abe8bc6fda
6 changed files with 70 additions and 6 deletions

View File

@ -2,6 +2,7 @@ import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.InvocationTargetException;
public class Reflection {
public static boolean booleanMethod() {
@ -92,6 +93,10 @@ public class Reflection {
expect(args[0] == String.class);
}
public static void throwOOME() {
throw new OutOfMemoryError();
}
public static void main(String[] args) throws Exception {
innerClasses();
annotations();
@ -130,5 +135,50 @@ public class Reflection {
expect("[Ljava.lang.Class;".equals(array[0].getClass().getName()));
expect(Class[].class == array[0].getClass());
expect(array.getClass().getComponentType() == array[0].getClass());
try {
Foo.class.getMethod("foo").invoke(null);
expect(false);
} catch (ExceptionInInitializerError e) {
expect(e.getCause() instanceof MyException);
}
try {
Foo.class.getConstructor().newInstance();
expect(false);
} catch (NoClassDefFoundError e) {
// cool
}
try {
Foo.class.getField("foo").get(null);
expect(false);
} catch (NoClassDefFoundError e) {
// cool
}
{ Method m = Reflection.class.getMethod("throwOOME");
try {
m.invoke(null);
} catch(Throwable t) {
expect(t.getClass() == InvocationTargetException.class);
}
}
}
}
class Foo {
static {
if (true) throw new MyException();
}
public Foo() { }
public static int foo;
public static void foo() {
// ignore
}
}
class MyException extends RuntimeException { }