Merge pull request #118 from dicej/master

fix exception wrapping for Method.invoke and static initializers
This commit is contained in:
Joshua Warner 2013-12-06 07:13:41 -08:00
commit d17bbc6d1b
6 changed files with 70 additions and 6 deletions

View File

@ -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() {

View File

@ -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:

View File

@ -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();

View File

@ -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));

View File

@ -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);
}

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 { }