FindBugs
Monday, February 9th, 2009Desde hace un tiempo venimos usando FindBugs en el proyecto en el que estoy. Para el que no lo conozca, aunque por el nombre es fácil de adivinar, se trata de una herramienta para la detección automática de posibles bugs en nuestro código.
Antes de nada decir que esta aplicación sirve para analizar código Java y que requiere una versión de la JRE (o JDK) igual o superior a la 1.5.0. No obstante, esta “limitación” es solo para correr la herramienta, ya que es capaz de detectar posibles bugs en código compilado para cualquier versión de Java.
Aunque existe una versión stand-alone de la aplicación nosotros utilizamos un plugin para Eclipse que funciona a partir de la versión 3.3. Este plugin integra las funcionalidades de FindBugs en el entorno de desarrollo, creando menús contextuales para las acciones principales y aportando una página de preferencias donde personalizar el comportamiento de la herramienta.
Lo que hace FindBugs es simple: aplicar una serie de patrones para identificar código susceptible de ser un bug. El número de estos patrones es bastante elevado y de diferente severidad. Aquí la lista completa.
Las principales categorías en qué dividen los bugs y algunos ejemplos son:
- Correctness
Código que tiene pinta de ser erroneo debido a una equivocación del programador.
Ejemplos:
* Hacer un cast imposible, que siempre va a lanzar una ClassCastException
* Aparentes bucles infinitos
* Método que define una variable que se llama igual que un atributo de la clase o superclase
* Una variable que se sabe que es null y se utiliza en un instanceof (siempre va a devolver false)
- Bad Practice
Cuando nos hemos saltado alguna de las buenas prácticas recomendadas.
Ejemplos:
* Comparar Strings utilizando == o != en vez de .equals()
* Comprobaciones en clases que definen alguno de los métodos equals() o hashCode()
* Uso de identificadores que son palabras reservadas en versiones superiores de Java
* Método suscetible de dejar abierto un Stream ante una excepción
- Dodgy
Código confuso, anómalo o escrito de forma un tanto ofuscada.
Ejemplos:
* Un método que utiliza el mismo código para dos ramas distintas de un if. Puede ser un copy/paste mal hecho.
* Código con una referencia “hardcodeada” a una ruta absoluta
* Procurar devolver un array de longitud cero antes que null.
* Implementar un interfaz que ya está siendo implementado por una superclase.
* Algún case de una sentencia switch no acaba con break y ejecutará el código del siguiente case.
Aparte de estos ejemplos mas o menos simples hay otros bastantes mas complejos (sobre todo a la hora de detectarlos en ejecución) como pueden ser:
* Un método sobrescribe a otro que se encuentra en una clase Adapter que implementa un listener de java.awt.event o javax.swing.event. Esta situación haría que el método no se llamase al ocurrir el evento.
* Una clase que extiende Servlet y utiliza atributos de clase. Como sólo se crea una instancia de cada Servlet y luego se usa en múltiples hilos de ejecución, es muy probable que esta situación de algún problema. Se recomienda usar únicamente variables locales a los métodos.
En fin, como ya os decía hay una gran cantidad de posibles errores que es capaz de detectar.
En cualquier momento podemos decirle a FindBugs que no nos avise de determinados bugs que no consideremos realmente importantes, como puede ser alguna de las buenas prácticas que sea demasiado estricta o que no nos afecte directamente ya que no estamos desarrollando código referente a alguno de esos temas.
En cuanto a cómo usarlo, o mas bien cuándo usarlo, depende de cada uno, pero mi recomendación es intentar hacer una pasada siempre que se vaya a subir código a CVS (o al sistema de control de versiones utilizado). Por ejemplo, en nuestro caso tenemos el código repartido en diferentes plugins de eclipse y, cada vez que tocamos código en uno de ellos o creamos uno nuevo, pasamos un análisis a todo el plugin para identificar posibles puntos conflictivos.
Y si aun no os he convencido del todo, un último pensamiento: ¿cuántas horas habéis perdido intentando solucionar un error para al final daros cuenta de que es que “faltaba un punto y coma aquí”?

