2011-05-16 15 views
242

Bueno, he tratado de entender y leer lo que podría causar, pero yo simplemente no puede conseguirlo:¿Qué podría causar java.lang.reflect.InvocationTargetException?

tengo en alguna parte de mi código siguiente:

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

cosa es que, cuando se intenta invocar algún método que arroja InvocationTargetException en lugar de alguna otra excepción esperada (específicamente ArrayIndexOutOfBoundsException). Como sé realmente qué método se invoca, fui directamente a este código de método y agregué un bloque try-catch para la línea que suponía arrojar ArrayIndexOutOfBoundsException y arrojó realmente ArrayIndexOutOfBoundsException como se esperaba. Sin embargo, al subirlo de alguna manera cambia a InvocationTargetException y en el código anterior catch(Exception e) e es InvocationTargetException y no como se esperaba.

¿Qué podría causar tal comportamiento o cómo puedo verificar tal cosa?

Respuesta

263

Has añadido un nivel extra de abstracción llamando al método con la reflexión. La capa de reflexión envuelve cualquier excepción en un InvocationTargetException, que le permite diferenciar entre una excepción en realidad causada por un error en la llamada de reflexión (tal vez su lista de argumentos no era válida, por ejemplo) y una falla dentro del método llamado .

Simplemente desenvuelve la causa dentro del InvocationTargetException y llegarás a la original.

+0

Gracias, pero ¿cómo difiero entre (AssertionError e) y (Exception e), por ejemplo? Si siempre obtengo InvocationTargetException primero antes de desenvolver la causa, ¿dónde diferiré entre cada excepción? – user550413

+3

@ user550413: Al desenvolver la excepción y examinar eso, por supuesto. Siempre puedes tirarlo tú mismo, y atraparlo de esa manera si es necesario. –

+119

Para cualquiera que se pregunte qué significa "desenvolver la causa dentro de' InvocationTargetException' ", descubrí que si lo imprimía usando' exception.printStackTrace() ', simplemente mira el" Caused By: " sección en lugar de la mitad superior/sección normal. – Jan

16

Desde el Javadoc de Method.invoke()

Lanza: InvocationTargetException - si el método subyacente se produce una excepción.

Esta excepción se produce si el método llamado arrojó una excepción.

+0

Imagine que tengo una cascada de instancias 'java.lang.reflect.Proxy' que aumentan un objeto envuelto. Cada 'Proxy' gestiona con gracia una excepción específica (posiblemente lanzada por el objeto envuelto) utilizando su propio' InvocationHandler'. Para que una excepción se propague a través de esta cascada hasta llegar al gestor/proxy de invocación correcto, en cada 'InvocationHandler', detectaría' InvocationTargetException', lo desenvolvería, verificaría si la excepción envuelta es 'instanceof' la excepción que debe manejar este 'InvocationHandler'. Si no es una 'instancia de', lanzaría la excepción ** desenvuelto ** ¿verdad? – Abdull

+0

Siempre lanzaría la excepción desenvuelta. –

39

La excepción si

InvocationTargetException - si el método subyacente se produce una excepción.

lo tanto, si el método, que ha sido invocada con el API de reflexión, se produce una excepción (excepción de ejecución, por ejemplo), la API de reflexión envolverá la excepción en un InvocationTargetException.

6

Esa InvocationTargetException probablemente esté terminando su ArrayIndexOutOfBoundsException. No se puede decir por adelantado cuando se utiliza la reflexión lo que ese método puede arrojar, por lo que en lugar de usar un enfoque throws Exception, todas las excepciones se capturan y se envuelven en InvocationTargetException.

+0

Gracias, pero ¿cómo difiero entre (AssertionError e) y (Exception e), por ejemplo? Si siempre obtengo InvocationTargetException primero antes de desenvolver la causa, ¿dónde diferiré entre cada excepción? – user550413

31

Utilice el método getCause() en el InvocationTargetException para recuperar la excepción original.

0
  1. Lista de todos los archivos jar desde el modo de Eclipse Navigator
  2. Compruebe que todos los archivos jar están en modo binario
+2

¿Cómo se verifica que los archivos jar estén en modo binario al verlos en el navegador? – William

1

This describe algo como,

InvocationTargetException es una excepción comprobada que envuelve una excepción lanzada por un método o constructor invocado. A partir del lanzamiento 1.4, esta excepción ha sido adaptada para cumplir con el mecanismo de encadenamiento de excepción de propósito general. La "excepción de destino" que es proporcionada en el momento de la construcción y se accedió a través del método getTargetException() ahora se conoce como la causa, y puede ser accedida mediante el método Throwable.getCause(), así como el "heredado" método."

0

Esta excepción se produce si el método subyacente (método llamado utilizando Reflection) arroja una excepción.

Así que si el método, que ha sido invocado por la API de reflexión, arroja una excepción (como por ejemplo la excepción de tiempo de ejecución), la API de reflexión ajustará la excepción a una InvocationTargetException.

8

Esto imprimirá la línea exacta de código en el método específico, que cuando se invoca, planteó la excepción:

try { 

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

} catch (InvocationTargetException e) { 

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

    // generic exception handling 
    e.printStackTrace(); 
} 
+0

Gracias; esto me ha ayudado a darme cuenta de que mi problema no estaba en el reflejo en sí, sino dentro del método invocado. –

-6

El error desapareció después de que hice Clean-> Ejecutar xDoclet-> Ejecutar xPackaging.

En mi espacio de trabajo, en ecllipse.

1

Es posible comparar con la clase de excepción original usando getCause() de la siguiente manera:

try{ 
    ... 
} catch(Exception e){ 
    if(e.getCause().getClass().equals(AssertionError.class)){ 
     // handle your exception 1 
    } else { 
     // handle the rest of the world exception 
    } 
} 
0

que estaba enfrentando el mismo problema. Usé e.getCause(). GetCause() y luego encontré que era debido a los parámetros incorrectos que estaba pasando. Hubo nullPointerException al recuperar el valor de uno de los parámetros. Espero que esto te ayude.

0

que tenían un error de java.lang.reflect.InvocationTargetException de una declaración llamando a un objeto en un registrador de class externa dentro de un bloque try/catch en mi class.

recorrer el código en el depurador de Eclipse & pasar el mouse sobre la declaración registrador vi el registrador object fue null (algunas constantes externos necesarios para crear una instancia en la parte superior de mi class).

Cuestiones relacionadas