Rififi
Rififi

Reputation: 121

Java: How to get full failure trace when invoking method with reflection?

for unit test purposes and template method pattern, I need to call some methods dynamically, like this:

//Unit test method call to wrap into a global test logic
Method m = myobject.getClass().getMethod("run");
m.invoke(...);

It's works, but when method fails (assertion fails or runtime exceptions), I can't have the full failure trace. For example, if you have a sequence call: method1() -> method2() -> method3() and the method3 fails, you have the following failure trace:

java.lang.<SomeError>:
at myexample.MyClass1.method3()
at myexample.MyClass1.method2()
at myexample.MyClass1.method1()
at myexample.Entrypoint.someEntrypoint()

It's the normal display when calling "method1()" explicitely in your code. But if you do: myobject.getClass().getMethod("method1").invoke(). If method3 fails, you have the following failure trace:

java.lang.<SomeError>:
at myexample.Entrypoint.someEntrypoint() // calling m.invoke()

So, when calling method1 with reflection (m.invoke()), the failure trace stops at invoke() instead of invoke() -> method2() -> method3(). There is a way to get the full trace ? Thanks.

NB: Thread.currentThread().getStackTrace() doesn't solve the problem and provides a similar output.

Upvotes: 2

Views: 1036

Answers (1)

Konstantin Yovkov
Konstantin Yovkov

Reputation: 62864

According to the javadoc, Method#invoke() will throw an InvocationTargetException

if the underlying method throws an exception.

So, just catch the InvocationTargetException and get the target exception that caused it.

Something like:

try {
   m.invoke();
catch (InvocationTargetException e) {
   Throwable originalException = e.getTargetException();
   for (StackTraceElement element : originalException.getStackTrace()) {
       System.out.println(el);
   }
}

Upvotes: 3

Related Questions