diff --git a/classpath/java/lang/ExceptionInInitializerError.java b/classpath/java/lang/ExceptionInInitializerError.java index d5014e9a35..1b39d248d8 100644 --- a/classpath/java/lang/ExceptionInInitializerError.java +++ b/classpath/java/lang/ExceptionInInitializerError.java @@ -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() { diff --git a/classpath/java/lang/reflect/Field.java b/classpath/java/lang/reflect/Field.java index debabdb0f3..5bb0bc6081 100644 --- a/classpath/java/lang/reflect/Field.java +++ b/classpath/java/lang/reflect/Field.java @@ -84,6 +84,8 @@ public class Field extends AccessibleObject { throw new IllegalArgumentException(); } + Classes.initialize(vmField.class_); + switch (vmField.code) { case ByteField: return Byte.valueOf @@ -171,6 +173,8 @@ public class Field 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 extends AccessibleObject { throw new IllegalArgumentException(); } + Classes.initialize(vmField.class_); + switch (vmField.code) { case ByteField: case BooleanField: diff --git a/classpath/java/lang/reflect/Method.java b/classpath/java/lang/reflect/Method.java index 55c7744c13..339db3dbb0 100644 --- a/classpath/java/lang/reflect/Method.java +++ b/classpath/java/lang/reflect/Method.java @@ -81,6 +81,8 @@ public class Method extends AccessibleObject implements Member { } if (arguments.length == vmMethod.parameterCount) { + Classes.initialize(vmMethod.class_); + return invoke(vmMethod, instance, arguments); } else { throw new ArrayIndexOutOfBoundsException(); diff --git a/src/avian/classpath-common.h b/src/avian/classpath-common.h index 4265c48998..b2c5fb7d45 100644 --- a/src/avian/classpath-common.h +++ b/src/avian/classpath-common.h @@ -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)); diff --git a/src/machine.cpp b/src/machine.cpp index cb3186c216..a338e9ac6b 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -4534,8 +4534,13 @@ postInitClass(Thread* t, object c) object exception = t->exception; t->exception = 0; - throwNew(t, Machine::ExceptionInInitializerErrorType, - static_cast(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); } diff --git a/test/Reflection.java b/test/Reflection.java index 764293f0af..cd75f68200 100644 --- a/test/Reflection.java +++ b/test/Reflection.java @@ -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 { }