traducir - NullPointerException en Java sin StackTrace
nullpointerexception java try catch (10)
He tenido instancias de nuestro código Java para capturar una NullPointerException
, pero cuando intento registrar el StackTrace (que básicamente termina llamando Throwable.printStackTrace()
), todo lo que obtengo es:
java.lang.NullPointerException
¿Alguien más ha encontrado esto? Intenté buscar en Google "rastro de pila vacía de puntero nulo de java" pero no encontré nada como esto.
(Su pregunta aún no está clara sobre si su código está llamando a printStackTrace()
o si lo está haciendo un controlador de registro).
Aquí hay algunas explicaciones posibles sobre lo que podría estar sucediendo:
El registrador / controlador que se está utilizando se ha configurado para emitir solo la cadena de mensaje de la excepción, no un seguimiento completo de la pila.
Su aplicación (o alguna biblioteca de terceros) está registrando la excepción usando
LOG.error(ex);
en lugar de la forma de 2 argumentos de (por ejemplo) el método log4j Logger.El mensaje viene de un lugar diferente a donde crees que está; por ejemplo, en realidad viene algún método de biblioteca de terceros, o algo aleatorio que queda de intentos anteriores de depuración.
La excepción que se está registrando ha sobrecargado algunos métodos para ocultar el seguimiento de pila. Si ese es el caso, la excepción no será una NullPointerException genuina, sino que será un subtipo personalizado de NPE o incluso alguna excepción no conectada.
Creo que la última explicación posible es bastante improbable, pero las personas al menos contemplan hacer este tipo de cosas para "evitar" la ingeniería inversa. Por supuesto, solo logra hacer la vida difícil para los desarrolladores honestos.
Aquí hay una explicación: jawspeak.com/2010/05/26/…
Lo he probado en Mac OS X
- versión java "1.6.0_26"
- Java (TM) SE Runtime Environment (compilación 1.6.0_26-b03-383-11A511)
VM de servidor de 64 bits de Java HotSpot (TM) (compilación 20.1-b02-383, modo mixto)
Object string = "abcd"; int i = 0; while (i < 12289) { i++; try { Integer a = (Integer) string; } catch (Exception e) { e.printStackTrace(); } }
Para este fragmento de código específico, 12288 iteraciones (¿+ frecuencia?) Parece ser el límite donde JVM ha decidido usar la excepción preasignada ...
Como mencionaste en un comentario, estás usando log4j. Descubrí (inadvertidamente) un lugar donde había escrito
LOG.error(exc);
en lugar de la típica
LOG.error("Some informative message", e);
A través de la pereza o tal vez simplemente no pensar en ello. La parte desafortunada de esto es que no se comporta como esperas. La API del registrador en realidad toma Objeto como el primer argumento, no como una cadena, y luego llama a la Cadena () al argumento. Así que, en lugar de obtener el bonito rastro de pila bonita, simplemente imprime el toString, que en el caso de NPE es bastante inútil.
Quizás esto es lo que estás experimentando?
Cuando está utilizando AspectJ en su proyecto, puede suceder que algún aspecto oculte su parte de la traza de la pila. Por ejemplo, hoy he tenido:
java.lang.NullPointerException:
at com.company.product.MyTest.test(MyTest.java:37)
Esta traza de pila se imprimió cuando se ejecutó la prueba a través de surefire de Maven.
Por otro lado, al ejecutar la prueba en IntelliJ, se imprimió un seguimiento de pila diferente:
java.lang.NullPointerException
at com.company.product.library.ArgumentChecker.nonNull(ArgumentChecker.java:67)
at ...
at com.company.product.aspects.CheckArgumentsAspect.wrap(CheckArgumentsAspect.java:82)
at ...
at com.company.product.MyTest.test(MyTest.java:37)
Esto generará la Excepción, use solo para depurar, debería manejar mejor sus excepciones.
import java.io.PrintWriter;
import java.io.StringWriter;
public static String getStackTrace(Throwable t)
{
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw, true);
t.printStackTrace(pw);
pw.flush();
sw.flush();
return sw.toString();
}
Hemos visto este mismo comportamiento en el pasado. Resultó que, por alguna extraña razón, si una NullPointerException ocurría en el mismo lugar en el código varias veces, luego de un tiempo usando Log.error(String, Throwable)
dejaría de incluir rastros completos de la pila.
Intenta mirar más atrás en tu registro. Usted puede encontrar al culpable.
EDITAR: este error parece relevante, pero se solucionó hace tanto que probablemente no sea la causa.
Probablemente esté utilizando Sun JVM, que realiza una gran optimización. Para recuperar los rastreos de la pila, debe pasar la opción -XX:-OmitStackTraceInFastThrow
a la JVM.
Las JVM OpenJDK modernas (¿1.8 y superiores?) Parecen aceptar también el -XX:-OmitStackTraceInFastThrow
(y tienen activada la optimización del seguimiento de la pila de forma predeterminada).
Sugerencia alternativa: si está utilizando Eclipse, puede establecer un punto de interrupción en la propia NullPointerException (en la perspectiva de depuración, vaya a la pestaña "Puntos de interrupción" y haga clic en el pequeño icono que tiene una!)
Verifique las opciones "atrapado" y "no capturado": ahora, cuando active el NPE, inmediatamente pasará al punto de interrupción y podrá avanzar y ver cómo se maneja exactamente y por qué no obtiene un seguimiento de la pila.
exception.toString
no le proporciona el StackTrace, solo devuelve
Una breve descripción de este lanzable. El resultado es la concatenación de:
* the name of the class of this object * ": " (a colon and a space) * the result of invoking this object''s getLocalizedMessage() method
Utilice exception.printStackTrace
lugar de generar el StackTrace.
toString()
solo devuelve el nombre de la excepción y el mensaje opcional. Sugeriría llamar
exception.printStackTrace()
para volcar el mensaje, o si necesita los detalles sangrientos:
StackTraceElement[] trace = exception.getStackTrace()