mirror of
https://github.com/corda/corda.git
synced 2025-01-03 19:54:13 +00:00
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:
parent
451fe159c2
commit
abe8bc6fda
@ -11,11 +11,11 @@
|
||||
package java.lang;
|
||||
|
||||
public class ExceptionInInitializerError extends Error {
|
||||
private final Throwable cause2;
|
||||
private final Throwable exception;
|
||||
|
||||
public ExceptionInInitializerError(String message) {
|
||||
super(message);
|
||||
cause2 = null;
|
||||
exception = null;
|
||||
}
|
||||
|
||||
public ExceptionInInitializerError() {
|
||||
|
@ -84,6 +84,8 @@ public class Field<T> extends AccessibleObject {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
Classes.initialize(vmField.class_);
|
||||
|
||||
switch (vmField.code) {
|
||||
case ByteField:
|
||||
return Byte.valueOf
|
||||
@ -171,6 +173,8 @@ public class Field<T> extends AccessibleObject {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
Classes.initialize(vmField.class_);
|
||||
|
||||
switch (vmField.code) {
|
||||
case ByteField:
|
||||
setPrimitive(target, vmField.code, vmField.offset, (Byte) value);
|
||||
@ -235,6 +239,8 @@ public class Field<T> extends AccessibleObject {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
Classes.initialize(vmField.class_);
|
||||
|
||||
switch (vmField.code) {
|
||||
case ByteField:
|
||||
case BooleanField:
|
||||
|
@ -81,6 +81,8 @@ public class Method<T> extends AccessibleObject implements Member {
|
||||
}
|
||||
|
||||
if (arguments.length == vmMethod.parameterCount) {
|
||||
Classes.initialize(vmMethod.class_);
|
||||
|
||||
return invoke(vmMethod, instance, arguments);
|
||||
} else {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
|
@ -567,13 +567,14 @@ invoke(Thread* t, object method, object instance, object args)
|
||||
}
|
||||
}
|
||||
|
||||
initClass(t, methodClass(t, method));
|
||||
|
||||
unsigned returnCode = methodReturnCode(t, method);
|
||||
|
||||
THREAD_RESOURCE0(t, {
|
||||
if (t->exception) {
|
||||
object exception = t->exception;
|
||||
t->exception = makeThrowable
|
||||
(t, Machine::InvocationTargetExceptionType, 0, 0, exception);
|
||||
(t, Machine::InvocationTargetExceptionType, 0, 0, t->exception);
|
||||
|
||||
set(t, t->exception, InvocationTargetExceptionTarget,
|
||||
throwableCause(t, t->exception));
|
||||
|
@ -4534,8 +4534,13 @@ postInitClass(Thread* t, object c)
|
||||
object exception = t->exception;
|
||||
t->exception = 0;
|
||||
|
||||
throwNew(t, Machine::ExceptionInInitializerErrorType,
|
||||
static_cast<object>(0), 0, exception);
|
||||
exception = makeThrowable
|
||||
(t, Machine::ExceptionInInitializerErrorType, 0, 0, exception);
|
||||
|
||||
set(t, exception, ExceptionInInitializerErrorException,
|
||||
throwableCause(t, exception));
|
||||
|
||||
throw_(t, exception);
|
||||
} else {
|
||||
classVmFlags(t, c) &= ~(NeedInitFlag | InitFlag);
|
||||
}
|
||||
|
@ -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 { }
|
||||
|
Loading…
Reference in New Issue
Block a user