salida - propagacion de excepciones en java
(Fuente desconocida) en el seguimiento de la pila de excepciones (6)
Fondo
Esta pregunta está relacionada con ¿Por qué String.valueOf (null) lanza una NullPointerException?
Considere el siguiente fragmento:
public class StringValueOfNull {
public static void main(String[] args) {
String.valueOf(null);
// programmer intention is to invoke valueOf(Object), but instead
// code invokes valueOf(char[]) and throws NullPointerException
}
}
Como se explica en la respuesta a la pregunta vinculada, la sobrecarga de métodos de Java resuelve la invocación anterior a String.valueOf(char[])
, que da como resultado una NullPointerException
en tiempo de ejecución.
Compilado en Eclipse y javac 1.6.0_17
, este es el seguimiento de la pila:
Exception in thread "main" java.lang.NullPointerException
at java.lang.String.<init>(Unknown Source)
at java.lang.String.valueOf(Unknown Source)
at StringValueOfNull.main(StringValueOfNull.java:3)
Tenga en cuenta que al rastreo de la pila anterior le falta la información KEY : ¡ NO tiene la firma completa del método valueOf
! Simplemente dice String.valueOf(Unknown Source)
!
En la mayoría de las situaciones que he encontrado, los rastreos de la pila de excepciones siempre tienen la firma completa de los métodos que están realmente en el seguimiento de la pila, lo que por supuesto es muy útil para identificar el problema inmediatamente y una razón importante por la cual el seguimiento de la pila dice que es bastante caro de construir) se proporciona en primer lugar.
Y, sin embargo, en este caso, el seguimiento de la pila no ayuda en absoluto . Ha fallado miserablemente al ayudar al programador a identificar el problema.
Como es, puedo ver 3 formas en que un programador puede identificar el problema con el fragmento de arriba:
- El programador se da cuenta por sí mismo de que el método está sobrecargado y, por regla de resolución, se invoca la sobrecarga "incorrecta" en este caso
- El programador usa un IDE bueno que le permite ver rápidamente qué método se selecciona
- En Eclipse, por ejemplo, el movimiento del mouse sobre la expresión anterior le dice rápidamente al programador que el valor de la
String valueOf(char[] data)
es de hecho el seleccionado
- En Eclipse, por ejemplo, el movimiento del mouse sobre la expresión anterior le dice rápidamente al programador que el valor de la
- El programador examina el bytecode (ugh!)
La última opción es probablemente la menos accesible, pero por supuesto es la Respuesta definitiva (un programador puede malinterpretar la regla de sobrecarga, IDE puede tener errores, pero los códigos de byte siempre (?) Dicen la verdad sobre lo que se está haciendo).
Las preguntas
- ¿Por qué el seguimiento de la pila es tan poco informativo en este caso con respecto a las firmas de los métodos que están realmente en el seguimiento de la pila?
- ¿Esto se debe al compilador? El tiempo de ejecución? ¿Algo más?
- ¿En qué otros escenarios (raros?) Puede el seguimiento de la pila no capturar información esencial como esta?
Ejecuté el código en Eclipse y obtuve la siguiente salida
public class Aloof {
public static void main(String[] args) {
String.valueOf(null);
}
}
Exception in thread "main" java.lang.NullPointerException
at java.lang.String.<init>(String.java:177)
at java.lang.String.valueOf(String.java:2840)
at mysql.Aloof.main(Aloof.java:19)
Si incluye la fuente completa (de JDK), puede depurar a la línea 177 en String.java
En Eclipse: Preferencias> Java> JRE instalados. La entrada marcada debe tener una ruta dentro del JDK, por ejemplo, C: / Archivos de programa (x86) / Java / jdk1.7.0_55 / jre.
Esto normalmente está relacionado con la información de depuración faltante. Probablemente esté utilizando JRE (no JDK), que no incluye información de depuración para las clases rt.jar. Intenta usar JDK completo, obtendrás las ubicaciones adecuadas en el seguimiento de la pila:
Exception in thread "main" java.lang.NullPointerException
at java.lang.String.<init>(String.java:177)
at java.lang.String.valueOf(String.java:2840)
at StringValueOfNull.main(StringValueOfNull.java:3)
Esto sucede cuando no hay información de depuración (línea) en la fuente o se le dice a la VM que arroje esa información a la hora de carga de la clase. Como tiene algunos números de línea, no es la configuración de VM, pero la clase String
tiene información de depuración.
Tenga en cuenta que si está utilizando la compilación Ant y si el atributo de depuración se establece en falso en el comando javac esto podría suceder.
por ejemplo: si necesita una ubicación adecuada en el conjunto de rastreo debug = true en Ant build,
<javac verbose="false" srcdir="${src}" destdir="${classdir}" debug="true" includes="**/*.java">
<classpath refid="compile.classpath" />
</javac>
Tuve el mismo problema, estoy usando Spring y Apache Ant para una integración continua.
El error que tuve fue en el archivo build.xml.
El registro de cambio de género con contenido más preciso fue:
build.xml con el error:
<javac srcdir="${src.home}" destdir="${work.home}/WEB-INF/classes">
<classpath refid="compile.classpath" />
</javac>
build.xml sin error:
<javac srcdir="${src.home}" destdir="${work.home}/WEB-INF/classes" debug="true">
<classpath refid="compile.classpath" />
</javac>
Dentro de la estructura carecía del coraje debug = "true"