¿Qué podría causar java.lang.reflect.InvocationTargetException?

Bueno, traté de entender y leer qué podría causarlo, pero simplemente no puedo entenderlo:

Tengo esto en algún lugar de mi código:

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

La cosa es que, cuando intenta invocar algún método, lanza InvocationTargetException en lugar de alguna otra excepción esperada (específicamente ArrayIndexOutOfBoundsException). Como realmente sé 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 se supone que arroja ArrayIndexOutOfBoundsException y realmente arrojó ArrayIndexOutOfBoundsException como se esperaba. Sin embargo, cuando sube, de alguna manera cambia a InvocationTargetException y en el código de arriba catch(Exception e) es InvocationTargetException y no ArrayIndexOutOfBoundsException como se esperaba.

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

preguntado el 16 de mayo de 11 a las 16:05

13 Respuestas

Ha agregado un nivel extra de abstracción llamando al método con reflexión. La capa de reflexión envuelve cualquier excepción en un InvocationTargetException, que le permite diferenciar entre una excepción Realmente causado por una falla 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 desenvuelva la causa dentro del InvocationTargetException y llegarás al original.

Respondido 10 Abr '15, 13:04

@ user550413: Desenvolviendo la excepción y examinándola, por supuesto. Siempre puedes tirarlo tú mismo y atraparlo de esa manera si es necesario. - Jon Skeet

Para cualquiera que se pregunte qué significa "desenvolver la causa dentro del InvocationTargetException", Acabo de descubrir que si lo tienes impreso con exception.printStackTrace(), basta con mirar la sección "Causado por:" en lugar de la mitad superior / sección normal. - Ene

Para agregar la explicación sobre "desenvolver", también puede capturar la excepción y usar el método getCause () en ella, que también se puede volver a lanzar, si lo desea. Algo como try {...} catch (InvocationTargetException ex) { log.error("oops!", ex.getCause()) } or ...catch... { throw ex.getCause() } - jcadcell

+1 @HJanrs para you just look at the "Caused By:" section instead of the top half/normal section - Cabeza de jengibre

@DheraajBhaskar No edite las respuestas de otras personas como si fueran suyas, y no use formato de cita para el texto que no se cita. Esa edición debería haberse publicado como comentario. - user207421

La excepción se lanza si

InvocationTargetException: si el método subyacente genera una excepción.

Entonces, si el método, que se ha invocado con la API de reflexión, arroja una excepción (excepción de tiempo de ejecución, por ejemplo), la API de reflexión envolverá la excepción en una InvocationTargetException.

contestado el 16 de mayo de 11 a las 21:05

gran explicación! - Gaurav

¿Qué sucede si espero que el método subyacente arroje una excepción? ¿Debo capturar esta excepción y simplemente volver a lanzar? - jDub9

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

respondido 05 nov., 12:11

Desde el Javadoc de Method.invoke ()

Lanza: InvocationTargetException: si el método subyacente arroja una excepción.

Esta excepción se lanza si el método llamado lanzó una excepción.

Respondido 13 Abr '17, 13:04

Así que imagina que tengo una cascada de java.lang.reflect.Proxy instancias que aumentan un objeto envuelto. Cada Proxy maneja con gracia una excepción específica (posiblemente lanzada por el objeto envuelto) usando su propio InvocationHandler. Para que una excepción se propague a través de esta cascada hasta alcanzar el controlador / proxy de invocación correcto, en cada InvocationHandlerYo atraparia InvocationTargetException, desenvuélvalo, compruebe si la excepción envuelta es una instanceof la excepción a ser manejada por este InvocationHandler. Si no es un instanceof, Arrojaría el sin envolver excepción ... ¿verdad? - Abdull

Siempre lanzaría la excepción sin envolver. - Peter Lawrey

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

try {

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

} catch (InvocationTargetException e) {

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

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

contestado el 26 de mayo de 15 a las 14:05

Gracias; esto me ha ayudado a darme cuenta de que mi problema no estaba en la reflexión en sí, sino en el método invocado. - Jose gómez

Esa InvocationTargetException probablemente está terminando tu ArrayIndexOutOfBoundsException. Cuando se usa la reflexión, no se sabe por adelantado lo que ese método puede arrojar, así que en lugar de usar un throws Exception enfoque, todas las excepciones están siendo atrapadas y envueltas en InvocationTargetException.

contestado el 16 de mayo de 11 a las 21:05

Gracias, pero ¿en qué me diferenciaré 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

Este patrón de describe algo como,

InvocationTargetException es una excepción marcada que envuelve una excepción lanzada por un método o constructor invocado. A partir de la versión 1.4, esta excepción se ha actualizado para ajustarse al mecanismo de encadenamiento de excepciones de propósito general. La "excepción de destino" que se proporciona en el momento de la construcción y a la que se accede mediante el método getTargetException () ahora se conoce como la causa, y se puede acceder a ella mediante el método Throwable.getCause (), así como el "método heredado" antes mencionado.

Respondido el 17 de Septiembre de 14 a las 18:09

Puede comparar con la clase de excepción original usando el método getCause () como este:

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

Respondido el 31 de diciembre de 17 a las 02:12

Yo tenía un java.lang.reflect.InvocationTargetException error de una declaración que llama a un objeto registrador en un externo class dentro de una try / catch bloquear en mi class.

Pasando por el código en el depurador de Eclipse y pasando el mouse sobre la declaración del registrador, vi el registrador object sí estaba null (algunas constantes externas necesitaban ser instanciadas en la parte superior de mi class).

Respondido el 14 de diciembre de 17 a las 12:12

Esta excepción se lanza si el método subyacente (método llamado usando Reflection) lanza una excepción.

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

respondido 05 nov., 14:12

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

Respondido el 17 de junio de 17 a las 21:06

  1. Enumere todos los archivos jar del modo Eclipse Navigator
  2. Verifique que todos los archivos jar estén en modo binario

respondido 09 nov., 12:12

¿Cómo verifica exactamente que los archivos jar están en modo binario al verlos en el navegador? - William

@William me hiciste reír jajaja. La respuesta de este tipo debería ser rechazada. - Karim Manaouil

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

En mi espacio de trabajo, en ecllipse.

contestado el 02 de mayo de 16 a las 16:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.