Java.lang.reflect.InvocationTargetException является оберткой для исключения, которое было вызвано вызванным методом. Если вызванный метод в свою очередь вызывает другой
Java.lang.reflect.InvocationTargetException является оберткой для исключения, которое было вызвано вызванным методом. Если вызванный метод в свою очередь вызывает другой метод, и этот второй метод вызывает исключение, это исключение будет «завернуто» в InvocationTargetException.
Пример
public class Test { public void testMethod() { throw new RuntimeException("Test"); } } public class Main { public static void main(String[] args) throws Exception { Test test = new Test(); Method method = Test.class.getMethod("testMethod"); try { method.invoke(test); } catch (InvocationTargetException e) { throw e.getCause(); } } }
В данном примере вызов method.invoke(test);
вызывает исключение RuntimeException("Test")
, которое исходит из метода testMethod()
. Это исключение затем «заворачивается» в InvocationTargetException
.
Причины и решение
InvocationTargetException является оберткой, и основное исключение, которое было вызвано в вызываемом методе, можно получить, вызвав метод getCause()
у объекта InvocationTargetException
.
В обратной стороне этого исключения содержится стек вызовов, который ведет к методу, где было вызвано исключение. Это помогает в отладке, так как позволяет быстро найти место, в котором возникло исключение.
Поэтому, когда возникает InvocationTargetException
, важно получить исходное исключение с помощью метода getCause()
и обработать его, вместо того чтобы просто ловить InvocationTargetException
. Это поможет выявить истинную причину проблемы.
try { method.invoke(object, args); } catch (InvocationTargetException e) { Throwable cause = e.getCause(); // обрабатываем исключение cause }
В данном примере cause
будет исключением, которое было вызвано внутри вызываемого метода. Обработка исключения cause
дает больше информации о проблеме и помогает быстрее найти и исправить ее.
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?
asked May 16, 2011 at 16:57
1
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() }
answered May 16, 2011 at 17:00
Jon SkeetJon Skeet
1.4m868 gold badges9136 silver badges9198 bronze badges
14
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
.
answered May 16, 2011 at 17:01
Andreas DolkAndreas Dolk
113k19 gold badges180 silver badges268 bronze badges
1
Use the getCause()
method on the InvocationTargetException
to retrieve the original exception.
Sumit Singh
15.7k6 gold badges61 silver badges89 bronze badges
answered Jun 30, 2012 at 18:32
Daniel WardDaniel Ward
4915 silver badges2 bronze badges
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.3k3 gold badges14 silver badges27 bronze badges
answered May 16, 2011 at 17:00
Peter LawreyPeter Lawrey
526k79 gold badges752 silver badges1130 bronze badges
2
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();
}
answered Dec 22, 2014 at 22:56
Rocky IndeRocky Inde
1,5111 gold badge20 silver badges27 bronze badges
0
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
.
answered May 16, 2011 at 17:01
LivLiv
6,0061 gold badge22 silver badges29 bronze badges
1
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.»
answered Dec 11, 2013 at 16:56
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
}
}
answered Nov 9, 2016 at 15:12
MehdiMehdi
1,36015 silver badges23 bronze badges
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
).
answered Dec 14, 2017 at 9:28
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
answered Dec 13, 2021 at 13:47
jobbertjobbert
3,29727 silver badges43 bronze badges
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.
answered Nov 5, 2014 at 9:16
Nikhil KumarNikhil Kumar
2,6383 gold badges21 silver badges24 bronze badges
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.
answered Jun 17, 2017 at 18:10
Deepak VajpayeeDeepak Vajpayee
3482 gold badges4 silver badges15 bronze badges
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.
answered May 27, 2022 at 14:56
- List all jar files from the Eclipse Navigator mode
- Verify that all the jar files are in binary mode
j0k
22.6k28 gold badges79 silver badges90 bronze badges
answered Nov 9, 2012 at 8:17
ManikManik
91 bronze badge
2
The error vanished after I did
Clean->Run xDoclet->Run xPackaging.
In my workspace, in ecllipse.
answered May 2, 2016 at 13:32
Ashutosh AnandAshutosh Anand
1693 gold badges3 silver badges14 bronze badges
0
Overview
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.
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.
What is Java reflection?
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.
What causes java.lang.reflect.InvocationTargetException?
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.
How to handle with java.lang.reflect.InvocationTargetException?
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.
Conclusion
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
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.
Автор оригинала: baeldung.
1. Обзор
При работе с Java Reflection API часто встречается java.lang.reflect.InvocationTargetException . В этом уроке мы рассмотрим его и то, как с ним справиться, на простом примере .
В основном это происходит, когда мы работаем со слоем отражения и пытаемся вызвать метод или конструктор, который сам создает базовое исключение.
Слой отражения обертывает фактическое исключение, вызванное методом, с помощью исключения InvocationTargetException . Давайте попробуем понять это на примере.
Давайте напишем класс с методом, который намеренно создает исключение:
public class InvocationTargetExample { public int divideByZeroExample() { return 1 / 0; } }
Теперь давайте вызовем описанный выше метод, используя отражение в простом тесте JUnit 5:
InvocationTargetExample targetExample = new InvocationTargetExample(); Method method = InvocationTargetExample.class.getMethod("divideByZeroExample"); Exception exception = assertThrows(InvocationTargetException.class, () -> method.invoke(targetExample));
В приведенном выше коде мы утвердили исключение InvocationTargetException , которое возникает при вызове метода. Здесь важно отметить, что фактическое исключение – ArithmeticException в данном случае – оборачивается в InvocationTargetException.
Теперь вопрос, который приходит на ум, заключается в том, почему отражение не создает фактическое исключение в первую очередь?
Причина в том, что это позволяет нам понять, произошло ли Исключение из-за сбоя при вызове метода через слой отражения или оно произошло внутри самого метода.
3. Как обрабатывать исключение InvocationTargetException?
Здесь фактическое базовое исключение является причиной InvocationTargetException , поэтому мы можем использовать Throwable.getCause () , чтобы получить дополнительную информацию об этом.
Давайте посмотрим, как мы можем использовать getCause() для получения фактического исключения в том же примере, который использовался выше:
assertEquals(ArithmeticException.class, exception.getCause().getClass());
Здесь мы использовали метод getCause() для того же объекта exception , который был брошен. И мы утверждали ArithmeticException.class как причина исключения.
Таким образом, как только мы получим базовое исключение, мы можем перестроить его, обернуть в какое-то пользовательское исключение или просто зарегистрировать исключение в соответствии с нашими требованиями.
4. Заключение
В этой короткой статье мы рассмотрели, как слой отражения обертывает любое базовое исключение. Мы также видели, как определить основную причину исключения InvocationTargetException и как справиться с таким сценарием на простом примере.
Как обычно, код, используемый в этой статье, доступен на GitHub .
If a InvocationTargetException
is a checked exception in Java that wraps an exception thrown by an invoked method or constructor. The method or constructor that throws the exception is invoked using the Method.invoke()
method. The InvocationTargetException
is quite common when using the Java Reflection API.
The Java reflection layer wraps any exception as an InvocationTargetException
. This helps clarify whether the exception is caused by an issue in the reflection call or within the called method.
What Causes InvocationTargetException
The InvocationTargetException
occurs mainly when working with the Java reflection API to invoke a method or constructor, which throws an exception.
This underlying exception is the actual cause of the issue, therefore resolving the InvocationTargetException
equates to finding and resolving the underlying exception that occurs within the invoked method.
InvocationTargetException Example
Here is an example of a InvocationTargetException
thrown when a method that is called using Method.invoke()
throws an exception:
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class InvocationTargetExceptionExample {
public int divideByZero() {
return 1 / 0;
}
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException {
InvocationTargetExceptionExample itee = new InvocationTargetExceptionExample();
Method method = InvocationTargetExceptionExample.class.getMethod("divideByZero");
try {
method.invoke(itee);
} catch (InvocationTargetException ite) {
ite.printStackTrace();
}
}
}
In this example, the main() method invokes divideByZero()
using Method.invoke()
. Since divideByZero()
throws an ArithmeticException
, it is wrapped within an InvocationTargetException thrown in the main()
method:
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 InvocationTargetExceptionExample.main(InvocationTargetExceptionExample.java:13)
Caused by: java.lang.ArithmeticException: / by zero
at InvocationTargetExceptionExample.divideByZero(InvocationTargetExceptionExample.java:6)
... 5 more
How to Resolve InvocationTargetException
Since the underlying exception is the actual cause of the InvocationTargetException
, finding and resolving the underlying exception resolves the InvocationTargetException
. The getCause()
method of the Throwable
class can be used to obtain the underlying exception. The earlier example can be updated accordingly to get the underlying exception and print its stack trace:
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class InvocationTargetExceptionExample {
public int divideByZero() {
return 1 / 0;
}
public static void main(String[] args) throws NoSuchMethodException {
InvocationTargetExceptionExample itee = new InvocationTargetExceptionExample();
Method method = InvocationTargetExceptionExample.class.getMethod("divideByZero");
try {
method.invoke(itee);
} catch (InvocationTargetException ite) {
Throwable underlyingException = ite.getCause();
underlyingException.printStackTrace();
} catch (IllegalAccessException iae) {
iae.printStackTrace();
}
}
}
Running the above will print out the stack trace of the underlying ArithmeticException
:
java.lang.ArithmeticException: / by zero
at InvocationTargetExceptionExample.divideByZero(InvocationTargetExceptionExample.java:6)
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 InvocationTargetExceptionExample.main(InvocationTargetExceptionExample.java:13)
The stack trace can then be inspected to resolve the underlying exception. This will also resolve the wrapped InvocationTargetException
.
Track, Analyze and Manage Java Errors With Rollbar
Managing errors and exceptions in your code is challenging. It can make deploying production code an unnerving experience. Being able to track, analyze, and manage errors in real-time can help you to proceed with more confidence. Rollbar automates Java error monitoring and triaging, making fixing errors easier than ever. Try it today.