370

Well, I've tried to understand and read what could cause it but I just can't get it:

I have this somewhere in my code:

 try{
 ..
 m.invoke(testObject);
 ..
 } catch(AssertionError e){
 ...
 } catch(Exception e){
 ..
 }

Thing is that, when it tries to invoke some method it throws InvocationTargetException instead of some other expected exception (specifically ArrayIndexOutOfBoundsException). As I actually know what method is invoked I went straight to this method code and added a try-catch block for the line that suppose to throw ArrayIndexOutOfBoundsException and it really threw ArrayIndexOutOfBoundsException as expected. Yet when going up it somehow changes to InvocationTargetException and in the code above catch(Exception e) e is InvocationTargetException and not ArrayIndexOutOfBoundsException as expected.

What could cause such a behavior or how can I check such a thing?

Cortex
  • 85
  • 8
user550413
  • 4,609
  • 4
  • 25
  • 26

15 Answers15

377

You've added an extra level of abstraction by calling the method with reflection. The reflection layer wraps any exception in an InvocationTargetException, which lets you tell the difference between an exception actually caused by a failure in the reflection call (maybe your argument list wasn't valid, for example) and a failure within the method called.

Just unwrap the cause within the InvocationTargetException and you'll get to the original one.

To do that, you can do exception.printStackTrace() and look at the "Caused By:" section instead of the top half/normal section.

You can also catch the exception and use the getCause() method on it, which can also be re-thrown, if desired. Something like try {...} catch (InvocationTargetException ex) { log.error("oops!", ex.getCause()) } or ...catch... { throw ex.getCause() }

A Jar of Clay
  • 5,622
  • 6
  • 25
  • 39
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Thanks, but that how will I differ between (AssertionError e) and (Exception e) for example? If I always get InvocationTargetException first before unwrapping the cause where will I differ between each exception? – user550413 May 16 '11 at 17:32
  • 5
    @user550413: By unwrapping the exception and examining that, of course. You can always throw it yourself, and catch it that way if you must. – Jon Skeet May 16 '11 at 17:53
  • 180
    For anyone wondering about what it means to "unwrap the cause within the `InvocationTargetException`", I just discovered that if you've got it printed using `exception.printStackTrace()`, you just look at the "Caused By:" section instead of the top half/normal section. – Jan Feb 10 '12 at 19:42
  • 41
    To add the the explanation about "unwrapping" you can also catch the exception and use the getCause() method on it, which can also be rethrown, if desired. Something like `try {...} catch (InvocationTargetException ex) { log.error("oops!", ex.getCause()) }` or `...catch... { throw ex.getCause() }` – jcadcell Sep 13 '12 at 18:58
  • @JonSkeet I am looking at the same exception at my colleagues code. I have tried to trap the exception by enclosing the call to the culprit class in a try-catch block. But to our surprise, its not getting into the catch block at all!. Could someone tell me what I might be missing here. – Pavan Dittakavi Jul 23 '13 at 10:10
  • @Pavan: Can't really say with that much description; I suggest you try to put it in a short but complete program which reproduces the problem, then post a new question. – Jon Skeet Jul 23 '13 at 16:51
  • Adding more details to what @jcadcell has mentioned earlier, please refer to this link http://examples.javacodegeeks.com/java-basics/exceptions/java-lang-reflect-invocationtargetexception-how-to-handle-invocation-target-exception/ – Abhijeet Jan 08 '15 at 06:14
  • 1
    @DheraajBhaskar Don't edit other people's answers as though they were your own, and don't use quote formatting for text that isn't quoted. That edit should have been posted as a comment. – user207421 Apr 10 '15 at 10:15
  • 1
    @EJP Actually the edit is already posted as a comment (68 upvotes) by Jan... The edit description specify "took suggestions from comments". – Jean-François Savard Aug 20 '15 at 14:02
  • I have similar issue but cannot resolve it, my question is here. Please have a look at that http://stackoverflow.com/questions/32709784/cannot-test-a-class-that-return-a-customexception – Jack Sep 22 '15 at 06:25
  • 1
    Does an `InvocationTargetException` always have a cause? – Jus12 Jan 05 '16 at 03:49
  • @Jus12: You can construct one without a cause, but I believe one that is thrown by `invoke` will always have one. – Jon Skeet Jan 05 '16 at 06:55
  • @Jan's comment above (look at "Caused By:" section of stacktrace) should be the answer. – a113nw Jun 06 '17 at 19:14
  • @jcadcell yes catch the exception and use the getCause() method on it work for me.Below is my code : } catch (IllegalAccessException | java.lang.InstantiationException | NoSuchMethodException | InvocationTargetException e) { System.out.println(e.getCause()); e.printStackTrace(); } – linjiejun Apr 20 '22 at 10:10
60

The exception is thrown if

InvocationTargetException - if the underlying method throws an exception.

So if the method, that has been invoked with reflection API, throws an exception (runtime exception for example), the reflection API will wrap the exception into an InvocationTargetException.

Andreas Dolk
  • 113,398
  • 19
  • 180
  • 268
49

Use the getCause() method on the InvocationTargetException to retrieve the original exception.

Sumit Singh
  • 15,743
  • 6
  • 59
  • 89
Daniel Ward
  • 491
  • 5
  • 2
24

From the Javadoc of Method.invoke()

Throws: InvocationTargetException - if the underlying method throws an exception.

This exception is thrown if the method called threw an exception.

gEdringer
  • 16,284
  • 3
  • 14
  • 27
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • So imagine I have a cascade of `java.lang.reflect.Proxy` instances augmenting a wrapped object. Each `Proxy` gracefully handles a specific exception (possibly thrown by the wrapped object) by using its own `InvocationHandler`. For an exception to ripple through this cascade until reaching the correct invocation handler/proxy, in each `InvocationHandler`, I would catch `InvocationTargetException`, unwrap it, check if the wrapped exception is an `instanceof` the exception to be handled by this `InvocationHandler`. If it's not an `instanceof`, I would throw the **unwrapped** exception... right? – Abdull Feb 25 '13 at 15:07
  • I would always throw the unwrapped exception. – Peter Lawrey Mar 05 '13 at 23:02
14

This will print the exact line of code in the specific method, which when invoked, raised the exception:

try {

    // try code
    ..
    m.invoke(testObject);
    ..

} catch (InvocationTargetException e) {

    // Answer:
    e.getCause().printStackTrace();
} catch (Exception e) {

    // generic exception handling
    e.printStackTrace();
}
ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
Rocky Inde
  • 1,511
  • 1
  • 20
  • 27
11

That InvocationTargetException is probably wrapping up your ArrayIndexOutOfBoundsException. There is no telling upfront when using reflection what that method can throw -- so rather than using a throws Exception approach, all the exceptions are being caught and wrapped up in InvocationTargetException.

Liv
  • 6,006
  • 1
  • 22
  • 29
  • Thanks, but that how will I differ between (AssertionError e) and (Exception e) for example? If I always get InvocationTargetException first before unwrapping the cause where will I differ between each exception? – user550413 May 16 '11 at 17:38
4

This describes something like,

InvocationTargetException is a checked exception that wraps an exception thrown by an invoked method or constructor. As of release 1.4, this exception has been retrofitted to conform to the general purpose exception-chaining mechanism. The "target exception" that is provided at construction time and accessed via the getTargetException() method is now known as the cause, and may be accessed via the Throwable.getCause() method, as well as the aforementioned "legacy method."

Mind Peace
  • 905
  • 8
  • 29
Sazzad Hissain Khan
  • 37,929
  • 33
  • 189
  • 256
2

You can compare with the original exception Class using getCause() method like this :

try{
  ...
} catch(Exception e){
   if(e.getCause().getClass().equals(AssertionError.class)){
      // handle your exception  1
   } else {
      // handle the rest of the world exception 
   }
} 
Mehdi
  • 1,340
  • 15
  • 23
1

I had a java.lang.reflect.InvocationTargetException error from a statement calling a logger object in an external class inside a try / catch block in my class.

Stepping through the code in the Eclipse debugger & hovering the mouse over the logger statement I saw the logger object was null (some external constants needed to be instantiated at the very top of my class).

Stuart Cardall
  • 2,099
  • 24
  • 18
1

A problem can also be that the targetSdkVersion is upped and that you use deprecated Gradle manifest features. Try lowering the targetSdkVersion again and see if it works. In my case it was targetSdkVersion 31 -> 30

jobbert
  • 3,297
  • 27
  • 43
0

This exception is thrown if the underlying method(method called using Reflection) throws an exception.

So if the method, that has been invoked by reflection API, throws an exception (as for example runtime exception), the reflection API will wrap the exception into an InvocationTargetException.

Nikhil Kumar
  • 2,618
  • 3
  • 21
  • 24
0

I was facing the same problem. I used e.getCause().getCause() then I found that it was because of wrong parameters I was passing. There was nullPointerException in fetching the value of one of the parameters. Hope this will help you.

Deepak Vajpayee
  • 348
  • 2
  • 4
  • 15
0

Invocation Target Exception:

I strongly believe that any naming convention has diligent thoughts invested in it. And, it is more than likely that our questions have their answers in the names, if we tried finding a rationale behind the name.

Let's break the name up into 3 parts. "Exception" has occurred when "Invoking" a "Target" method. And, the exception is thrown with this wrapper when, a method is invoked via reflection in Java. While executing the method, there could be any type of exception raised. It is by design, that the actual cause of the exception is abstracted away, to let the end user know that the exception was one that occurred during a reflection based method access. In order to get the actual cause, it is recommended that the exception is caught and ex.getCause() is called. Best practice is to, in fact throw the cause from the catch block that caught the InvocationTargetException

try{
    method.invoke();
} catch(InvocationTargetException ite) {
    throw ite.getCause();
} catch(Exception e) {
    // handle non-reflection originated exceptions
    throw e;
}

I know it is similar to the other answers, but I wanted to make it more clear about "when" this exception type is generated by Java, so that it is a mystery to none.

-4
  1. List all jar files from the Eclipse Navigator mode
  2. Verify that all the jar files are in binary mode
j0k
  • 22,600
  • 28
  • 79
  • 90
Manik
  • 9
  • 1
-9

The error vanished after I did Clean->Run xDoclet->Run xPackaging.

In my workspace, in ecllipse.

Ashutosh Anand
  • 169
  • 3
  • 3
  • 14