sábado, 18 de febrero de 2012

Debug de una aplicación Java

Java
Durante el desarrollo de una aplicación es normal que se produzcan excepciones y errores. Para descubrir sus causas y depurarlos se pueden utilizar varias herramientas. Una de ellas es utilizando un sistema de trazas como slf4j en el que podamos ver que ha estado haciendo la aplicación en el momento del fallo. Con la traza de la excepción la mayoría de las veces es suficiente para reproducir el error en una máquina de desarrollo pero en ocasiones hay «bugs» que si no se «tracean» o «debuggean» con un depurador no es fácil seguir la pista al código que se está ejecutando.

Para depurar una aplicación en Java hay que arrancar la máquina virtual en modo debug de tal forma que luego con un IDE como eclipse podamos depurar la aplicación. Los parámetros a añadir a la linea de comandos que arranca la JVM son:

-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n

Si estamos depurando una aplicación web que se ejecuta en el contenedor Tomcat los shell scripts que lo arrancan nos lo ponen más fácil, tan solo tendremos que iniciar Tomcat con el siguiente comando y él se encargará de pasar los parámetros anteriores a la JVM:

catalina.sh jpda start

Para arrancar Tomcat en modo debug desde Ant podemos utilizar la siguiente tarea:

...
<condition property="LIB_HOME" value="/home/picodotdev/java">
 <and><os family="unix"/></and>
</condition>

<property name="TOMCAT" value="apache-tomcat-7.0.25"/>

<condition property="TOMCAT_STARTUP" value="startup.sh">
 <and><os family="unix"/></and>
</condition>
<condition property="TOMCAT_CATALINA" value="catalina.sh">
 <and><os family="unix"/></and>
</condition>
<condition property="TOMCAT_SHUTDOWN" value="shutdown.sh">
 <and><os family="unix"/></and>
</condition>
...
<target name="serverStartDebug">
 <exec executable="${LIB_HOME}/${TOMCAT}/bin/${TOMCAT_CATALINA}" dir="${LIB_HOME}/${TOMCAT}/bin/">
     <arg line="jpda start"/>
 </exec>
    <waitfor maxwait="10" maxwaitunit="second">
     <socket server="localhost" port="8080"/>
 </waitfor>
</target>
...

Una vez que tenemos la máquina virtual arrancada en modo debug podremos depurar la aplicación desde un IDE. En el siguiente paso veremos como hacerlo desde eclipse. Para ello en el eclipse iremos al menú «Debug > Debug Configurations > Remote Java Application» e indicaremos los parámetros: proyecto que queremos depurar, tipo de conexión (Standard (Socket Attach)), Host (localhost, si la JVM donde está ejecutandose la aplicación es la máquina local) y puerto (8000, lo mismo indicado que en el parámetro address).


Dado que en realidad nos estamos conectando a la máquina virtual de Java de forma remota y a través de la red tal vez necesitemos abrir el puerto 8000. Si tenemos un sistema Linux y ufw como firewall lo podremos hacer con:

$ sudo ufw allow 8000
$ sudo ufw status


 Una vez hayamos realizado los pasos anteriores estamos listos para «debuggear», podremos añadir puntos de ruptura donde queramos en la aplicación y podremos ver las variables y sus valores presentes en el ámbito de donde se ha parado la aplicación.


Referencia:
http://wiki.apache.org/tomcat/FAQ/Developing#Q2