style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">

RTFS: Read The F.... Stacktrace

Tal vez hayas leido del acronimo RTFM, se utiliza en tipicamente (sobre todo en los foros de internet) cuando se le quiere indicar a alguien que para responder a su pregunta todo lo que tendria que haber hecho es leer el manual.

Bueno, quisiera proponerles un nuevo acronimo que me comento una amigo cuando estabamos platicando sobre los problemas a los que nos enfretamos todos los dias cuando estamos desarrollando: RTFS, la S es the StackTrace.

Cuando una aplicacion de Java se traba, en el 99% de los casos (a menos que le hayas logrado pegar a un bug de bajo nivel de la maquina virtual, cosa que ocurre muy pero muy rara vez)  la aplicacion te presentara a una StackTrace que te permitira saber no solamente en que linea ocurrio el problema, si no tambien que metodo(s) estaban llamando al metodo dentro del cual ocurrio el problema.

Digamos por ejemplo que  tenemos el metodo:

public static boolean areEqual(Object object1, Object object2) {
return object1.equals(object2);
}

Que ocurre cuando el parametro object1 es null? Pues una NullPointerException, que se nos presentara de la siguiente forma:

Exception in thread "main" java.lang.NullPointerException
    at JavaSnippet$1.equals(JavaSnippet.java:5)
    at JavaSnippet$1.run(JavaSnippet.java:11)
    at JavaSnippet.main(JavaSnippet.java:14)

Ahi podemos ver que el error ocurrio en la linea 5 del archivo “JavaSnippet.java”, cuando la linea 11  del mismo archivo fue invocada por la la linea 14, inclusive nos dice a que metodo pertenece cada linea de ejecucion!

Como ven, saber exactamente que linea causo un problema en java es algo muy facil, por que las excepciones incluyen la informacion de todo el camino que siguio la ejecucion del problema hasta el punto en que ocurrio la excepcion que interrmpio la ejecucion normal del programa: En el pasado quedaron los dias cuando al programar en C, C++ o Delphi y cometer el error de acceder un objeto no inicializado lo unico que veiamos era un mensaje del tipo:

0xC1114455 Access Violation Error

Ahi si que era mas dificil averiguar (aunque no siempre imposible si se contaba con las herramientas correctas y la memoria no estaba demasiado corrupta) exactamente en donde y por que habia ocurrido el problema.

Pero aun con lo facil que es saber donde y por que ocurrio un problema en Java, aun me encuentro muchos mensajes en los foros de programacion del tipo:

“Hice una aplicacion con que hace XXXX usando XXXX pero lanza una excepcion y se traba: ¿como lo compongo?”

Y ya, eso es todo lo que ponen, y la stacktrace, que deberia ir copiada y pegada siempre que se necesita ayuda para resolver este tipo de probemas? Esa brilla por su ausencia!. Mas de la mitad de las veces he resuelto el problema simplemente contestando: Podrias mostrarme la stacktrace? Y luego simplemente leyendosela a la persona... pero a veces se me antoja simplemente poner RTFS!

A las personas que hacen este tipo de preguntas muchas veces les sorprende que nadie les conteste, lo que no saben es que la mayoria de las personas en los foros, al ver una pregunta para la cual el autor ni siquiera se molesto en agregar el stacktrace, piensa: "Esta persona no tiene ni siquiera el nivel de conocimientos para saber que la respuesta a su pregunta esta frente a su cara, no tiene caso que le conteste, por que igual no va entender la respuesta, y solo conseguire frustrarme" y la dejan sin contestar.

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de ezamudio

aquí mismo...

y que tal esas dudas de tipo "es que mi programa no corre, me sale este error" y pegan el stack trace... aqui he visto algunos posts asi (mañana busco algunos y pego aqui las ligas, ahorita me da flojera la verdad). Creo que ahi se puede justificar 100% un RTFS. Según yo hace poco (esta semana) vi uno así.

Ademas el formato de Stack Trace es útil incluso en los casos en que se optimizó la compilación y no incluye números de linea ya el .class; sigue apareciendo el nombre de la clase y el método, lo cual ya es bastante útil para enfocarse a buscar la posible causa dentro de dicho método.

Imagen de willyxoft

Estoy de acuerdo, aunque

Estoy de acuerdo, aunque leer el stacktrace puede resultar confuso para los novatos que a duras penas si pueden leer código... y peor si les da la sensación que la información que brinda no ayuda de mucho, en el sentido que dice donde falla pero no como corregirlo. También en ocasiones la "culpa" de error no la tiene el código sino el contenedor u otro agente externo pero el Stacktrace no lo indica claramente, cosa que para quien no tiene experiencia no le ayuda en nada. En esos casos conviene leer también el log de los contenedores lo cual también implica leer mas stacktrace...
Lo que queda entonces es hacerles ver que que si bien leer el stacktrace por si solo no resuelve las cosas, mas cierto es que es un muy buen punto de inicio, por lo que alguien llegue con una duda y ni siquiera a mirado el stacktrace (al menos por curiosidad) es imperdonable. El segundo paso es pues aprender a interpretarlos, cosa obvia para algunos pero no para todos, y el tercero aprender a identificar errores comunes o frecuentes, éste último solo lo dá la experiencia, misma que sin embargo también puede ser consultada.

Saludos.

Imagen de luxspes

RTFSC: Read the F.... Source Code!

Se a lo que te refieres, es cuando ocurre el problema inverso, alguien entra a un foro y pone la pregunta:

Mi programa truena y manda esto:

Exception in thread "main" java.lang.NullPointerException
    at JavaSnippet$1.equals(JavaSnippet.java:5)
    at JavaSnippet$1.run(JavaSnippet.java:11)
    at JavaSnippet.main(JavaSnippet.java:14)

Que hago! Ayudenme! es urgente!

Lo primero que le contesto (si ando con paciencia ese dia) es: Sabes lo que significa el StackTrace? y luego: ¿Que dice la linea de codigo 5 del archivo JavaSnippet.java?

Y me contesta:

return object1.equals(object2);

Ahora, cuando es algún otro tipo de excepcion, 1 sola linea puede no ser suficiente para diagnoticarla, pero en el caso de una NullPointerException es muy simple significa que trataste de efectuar una operación sobre un objeto nulo. Por supuesto, si les contesto eso, invariablemente (si es en persona) se me quedan viendo con cara de "what?" y si es en linea me contestan que "no entienden de esos rollos, que apenas estan aprendiendo y que que significa eso de "objeto nulo""

Asi que he encontrado un modo mas sencillo de explicarlo:

Ese error ocurrio por que la variable antes del "." no esta inicializada, asi que ve a la linea 5 (que es la que indica el stracktrace) y averigua por que la variable antes del "." en esa linea no tiene ningun valor, haz que tenga valor, y asunto resuelto.

Por supuesto, a veces resulta que la linea con el problema es algo como:

return usuario.getDireccion().getCalle().equals(compañia.getSucursales().get(0).getDireccion().getCalle());

Una linea asi, sobretodo para alguien sin experiencia, resulta todo un misterio, tiene demasiados "." (puntos) de fallo que pueden producir la NullPointerException.... y como encontrar la solucion implicaria tener que leer todo el codigo de la persona con el problema (y en donde trabajo a veces eran 4 o 5 personas las que tenian este problema al mismo tiempo), pues he optado por una estrategia mas directa:

"Mira, tu linea tiene demasiados puntos, cada punto es un posible causante de la NullPointerException" asi que por favor, partela en pedacitos, asi:

Direccion direccionUsuario = usuario.getDireccion()
String calleUsuario = direccionUsuario.getCalle();

List sucursalesCompañia = compañia.getSucursales();
Sucursal sucursalCompañia = sucursalesCompañia.get(0);
Direccion direccionSucursal = sucursalCompañia.getDireccion();
String calleCompañia = direccionSucursal.getCalle();

return calleUsuario.equals(calleCompañia );

Y correlo otra ves, y en la linea que te truene, checa por la que la variable antes del unico "." no tiene ningun valor, corrige el codigo para que tenga valor, o agrega una condicional para evitar que esa linea se ejecute si la variable no tiene valor.

Y funciona como magia, despues de eso, nunca vuelven a tener problemas con las NullPointerException... ojala hubiera una solucion tan facil para todos los tipos de excepciones posibles...

Imagen de ezamudio

jstack

Otra razón muy importante por la cual es necesario saber leer un stack trace es para poder depurar situaciones de deadlock con jstack.

Si no lo han usado, jstack es una herramienta muy útil que imprime el stack trace de cada hilo de una aplicación que está corriendo. De ese modo pueden ver lo que está ocurriendo en cada hilo en ese momento, y si tienen algún problema de que su aplicación de repente se traba y sospechan que puede ser un problema de sincronización de procesos (algun deadlock) con esto lo pueden encontrar, viendo el status de cada hilo para encontrar los que digan BLOCKED (on object monitor) y ver si hay alguna relación entre dos (o más) hilos en el mismo status.

Imagen de Shadonwk

genial no lo habia visto

genial no lo habia visto pero ahora sera RTFS

Imagen de JaimeItlzc

StackTrace

Te lo juro que nunca habia checado eso como voy iniciando en la programacion en java estoy novato pero tu aportacion me va ayudar mucho a ala deteccion de problemas.

Saludos.

Saber sobre StackTrace

Saludos, definitivamente leer teóricamente sobre StrackTrace, es un aporte muy importante!

tengo este codigo de programacion y me sale ackage vv; import ja

ackage vv;
import java.io.*;
public class tools {

BufferedReader teclado;
/*este es el metodo para imprimir*/
void print(String msg)
{
System.out.print(msg);
}
/*metodo para leer enteros*/
double leeDouble(String msg) throws IOException
{
print(msg);
double res=0;
res=java.lang.Double.parseDouble(teclado.readLine());
return res;
}
/*metodo para instalacion del buffer*/

void inicio()
{
teclado=new BufferedReader(new InputStreamReader(System.in));
}
}

esta es otra clase

package vv;
import java.io.*;
public class ejec {
public static void main(String[] args) throws IOException
{

tools xx=new tools();
double v =xx.leeDouble("pu");

}

}

cuando le compilo me sale

Exception in thread "main" java.lang.NullPointerException
at vv.tools.leeDouble(tools.java:16)
at vv.ejec.main(ejec.java:8)

@karl Paradojicamente este

@karl Paradojicamente este post es precisamente para que leas el stacktrace que sale.

Exception in thread "main" java.lang.NullPointerException
at vv.tools.leeDouble(tools.java:16) <-------- AQUI
at vv.ejec.main(ejec.java:8)

El error está en la linea 16 del archivo tools.java en el método leeDouble, estás intentando llamar un método de algo que es nulo y nulo.metodo tira NullPointerException

Para arreglarlo tienes que ver que es lo que es nulo y luego hacer algo para que ya no sea nulo ( tip: cuando declaras un atributo su valor por default es "null" busca por ahí )

Saludos.

si pero co se q hacer at

si pero como se q hacer para q no sea null en --at vv.tools.leeDouble(tools.java:16)---- este es la linea 16--- res=java.lang.Double.parseDouble(teclado.readLine());
y no se q ponele para q ya no sea null..saludos

Quién crees que es el que es

Quién crees que es el que es nul en esa linea?

res=java.lang.Double.parseDouble(teclado.readLine());

Si la partimos:

res //no se le está asignando un valor
=  // no ... este es un operador
java.lang.Double.parseDouble // no la clase no puede ser null
teclado.readLine() // Si!!!!!

Entonces teclado es nulo y lo sé porque el stacktrace lo dice, yo no puedo ver tu código ni correrlo en tu máquina.

Entonces?

Pues haz algo para que no sea nulo, revisa el resto de tu código y entiende para que sirve. Ve si tienes ya algo para hacer que esta variable no sea nula.

Suerte!

style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">