Exception Handling is one of the most powerful mechanisms in Java. It is used to handle the runtime errors during execution so that in case of an error, you can prevent the program from crashing and the flow of the application can remain uninterrupted despite the error.
Table of Contents
If you have ever worked with Java Reflection API, you must have at least once encountered the java.lang.reflect.InvocationTargetException in your program. In this article, we will be understanding the InvocationTargetException, the reasons behind its occurrence, and how to properly handle it. The article also includes some appropriate examples for your ease.
Just for starters, Reflection is a feature in Java that allows a Java program to examine itself and manipulate the internal properties of the program during execution.
For instance, it is allowed for a Java class to obtain the names of all its members and display them while executing.
This feature to examine and manipulate a Java class from within itself may not seem to be a big thing and feels like a common feature, but surprisingly this feature does not exist in various renowned programming languages nor there is any alternative for it.
For instance, Cor C++ programmers have no possible way to obtain information about the functions defined within their program.
Java reflection offers some very significant uses, especially in JavaBeans, where software components can be tweaked visually using a builder tool.
The tool makes use of reflection to obtain the properties of the Java class when they are dynamically loaded.
See this code below demonstrating a simple example of using reflection
1. import java.lang.reflect.*; 2. 3. public class DumpMethods { 4. public static void main(String args[]) 5. { 6. try { 7. Class myClass = Class.forName(args[0]); 8. Method m[] = myClass.getDeclaredMethods(); 9. for (int i = 0; i < m.length; i++) 10. System.out.println(m[i].toString()); 11. } 12. catch (Throwable e) { 13. System.err.println(e); 14. } 15. } 16. }
This code snipped is for the invocation of:
java DumpMethods java.util.Stack
And the output is:
public java.lang.Object java.util.Stack.push( java.lang.Object) public synchronized java.lang.Object java.util.Stack.pop() public synchronized java.lang.Object java.util.Stack.peek() public boolean java.util.Stack.empty() public synchronized int java.util.Stack.search(java.lang.Object)
The output list down the names of all methods of class java.util.Stack, along with their fully qualified parameter and return types.
The InvocationTargetException is not the actual exception we have to deal with instead it is a checked exception that wraps the actual exception thrown by an invoked method or constructor. As of the release of JDK 2.4, this exception has been modified enough to be used as a general-purpose exception-chaining mechanism.
There have been some changes since the beginning as the “target exception” that is provided at the time of construction and is accessed through the getTargetException() method is now known as the cause method, and can be accessed via the Throwable.getCause() method, but the previously mentioned legacy method is also still applicable.
See this example of a java.lang.reflect.InvocationTargetException thrown when a method that is called using Method.invoke() throws an exception:
1. import java.lang.reflect.InvocationTargetException; 2. import java.lang.reflect.Method; 3. 4. public class InvocationTargetExceptionDemo { 5. public int dividedByZero() { 6. return 1 / 0; 7. } 8. 9. public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException { 10. InvocationTargetExceptionDemo invoked = new InvocationTargetExceptionDemo(); 11. Method method = InvocationTargetExceptionDemo.class.getMethod("divisionByZero"); 12. try { 13. method.invoke(invoked); 14. } catch (InvocationTargetException e) { 15. e.printStackTrace(); 16. } 17. } 18. }
In this example, the main() method invokes the dividedByZero() method using Method.invoke(). As dividedByZero() method will throw an ArithmeticException, it will be wrapped within an InvocationTargetException thrown in the main() method.
The output error is as shown:
java.lang.reflect.InvocationTargetException at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:564) at InvocationTargetExceptionDemo.main(InvocationTargetExceptionDemo.java:13) Caused by: java.lang.ArithmeticException: / by zero at InvocationTargetExceptionDemo.dividedByZero(InvocationTargetExceptionDemo.java:6) ... 5 more
As discussed earlier, the above mentioned code snippet along with its output has made it clear that the actual exception is the ArithmeticException and it got wrapped into an InvocationTargetException.
Now, the question that must come to your mind is why the reflection does not directly throw the actual exception instead of wrapping it into an InvocationTargetException? Why do we even need it? The reason is clear. It allows the programmer to first understand whether the exception has occurred due to some sort of failure in properly calling the method through the reflection layer or whether the exception has occurred within the method itself.
The java.lang.reflect.InvocationTargetException mainly occurs while working with the reflection layer. When you attempt to invoke a method or constructor and it throws an underlying exception, that underlying exception is the actual cause of the occurrence of java.lang.reflect.InvocationTargetException. The reflection layer wraps the actual exception thrown by the method with the InvocationTargetException thus you get the java.lang.reflect.InvocationTargetException in return.
To properly deal with the InvocationTargetException, you have to handle the actual underlying exception that is the main reason for InvocationTargetException. To cater to that, the Throwable.getCause() method is used to get more information about the exception such as the type of exception, after invocation. This information is undoubtedly very useful for resolving the java.lang.reflect.InvocationTargetException.
Consider the below example, it is an extension to the previous code example which intentionally generated an exception (divided by zero) in the method InvocationTargetExceptionDemo:
1. import java.lang.reflect.Method; 2. public class TestInvocationException { 3. public static void main(String[] args) { 4. InvocationDemo id = new InvocationDemo(); 5. ¬¬¬¬¬¬// Getting Access to all the methods of myInvocation Class: 6. Method[] m = InvocationDemo.class.getMethods(); 7. try { 8. // First method of the myInvocatio Class is invoked here 9. m[0].invoke(id); 10. } 11. catch(Exception e) { 12. // wrapper exception: 13. System.out.println("Wrapper exception: " + e); 14. // getCause method is used with the actual exception: 15. System.out.println("Underlying exception: " + e.getCause()); 16. } 17. } 18. } 19. 20. class myInvocation{ 21. public void InvocationTargetExceptionDemo() { 22. // Dividing by zero again 23. System.out.println(3 / 0); 24. } 25. }
Output generated from the getCause() method is shown below, it clearly states the type of underlying exception:
Wrapper exception: java.lang.reflect.InvocationTargetException Underlying exception: java.lang.ArithmeticException: / by zero
Here, the getCause() method is used with the same exception object that was thrown and it is identified that ArithmeticException.class is the cause of the InvocationTargetException.
Now, it may seem very easy as programmers can easily identify the divided by zero error from the code and exception for it may be already known but suppose you are dealing with any other exception and your code is significantly longer and more complex, just the name of the exception from the getCause() method can come in very handy.
Also Read: How to use Java Generic Interface
So, once you get the reason behind the underlying exception, you can also re-throw the same exception, you can also wrap it in some custom exception, or you can also log the exception based on your requirement.
Exceptions are the best way to deal with errors in any programming language. Proper knowledge of exceptions and their dealing can be a lifesaver for a Java coder on many occasions.
In this comprehensive article, we have explored the java.lang.reflect.invocationtargetException.
We discussed how the reflection layer wraps an underlying exception in Java. To be precise, when we invoke a class using the Method.invoke(), and if it throws an exception; it will be wrapped by the java.lang.reflect.InvocationTargetException class. We have also seen how to determine the underlying reason behind the occurrence of InvocationTargetException and how to handle such a problem in your Java code.
Shaharyar Lalani is a developer with a strong interest in business analysis, project management, and UX design. He writes and teaches extensively on themes current in the world of web and app development, especially in Java technology.
Create a free profile and find your next great opportunity.
Sign up and find a perfect match for your team.
Xperti vets skilled professionals with its unique talent-matching process.
Connect and engage with technology enthusiasts.
© Xperti.io All Rights Reserved
Privacy
Terms of use