Análisis de código fuente con las API de Java 6

por Seema Richard, Deepa Sobhana

¿Alguna vez ha pensado en cómo herramientas como Checkstyle o FindBugs realizan un análisis de código estático, o cómo los entornos de desarrollo integrados (IDE) como NetBeans o Eclipse ejecutan correcciones rápidas de código o encuentran las referencias exactas de un campo declarado en su código? En muchos casos, los IDE tienen sus propias API para analizar el código fuente y generar una estructura de árbol estándar, denominada Árbol de sintaxis abstracta (AST) o "árbol de análisis", que se puede utilizar para un análisis más profundo de los elementos fuente. La buena noticia es que ahora es posible realizar dichas tareas y muchas más con la ayuda de tres nuevas API introducidas en Java como parte de la versión 6 de Java Standard Edition. Las API que pueden ser de interés para los desarrolladores de aplicaciones Java que necesitan realizar análisis de código fuente son la API del compilador de Java (JSR 199),la API de procesamiento de anotaciones conectables (JSR 269) y la API del árbol del compilador.

En este artículo, exploramos las características de cada una de estas API y desarrollamos una aplicación de demostración simple que verifica ciertas reglas de codificación de Java en un conjunto de archivos de código fuente suministrados como entrada. Esta utilidad también muestra los mensajes de violación de codificación, así como la ubicación del código fuente violado como salida. Considere una clase Java simple que anula el método equals () de la clase Object. La regla de codificación que se debe verificar es que cada clase que implemente el método equals () también debe anular el método hashcode () con la firma adecuada. Puede ver que la clase TestClass a continuación no define el método hashcode (), aunque tiene el método equals ().

public class TestClass implements Serializable { int num; @Override public boolean equals(Object obj)  } 

Continuemos y analicemos esta clase como parte del proceso de construcción con la ayuda de estas tres API.

Invocación del compilador desde el código: API del compilador de Java

Todos usamos la javacherramienta de línea de comandos para compilar archivos fuente de Java en archivos de clases. Entonces, ¿por qué necesitamos una API para compilar archivos Java? Bueno, la respuesta es bastante simple: como su nombre lo describe, esta nueva API estándar nos permite invocar el compilador desde nuestras propias aplicaciones Java; es decir, puede interactuar mediante programación con el compilador y, por lo tanto, hacer que la compilación forme parte de los servicios de nivel de aplicación. Algunos usos típicos de esta API se enumeran a continuación.

  • La API del compilador ayuda a los servidores de aplicaciones a minimizar el tiempo necesario para implementar aplicaciones, por ejemplo, evitando la sobrecarga de usar un compilador externo para compilar las fuentes de servlets generadas a partir de las páginas JSP.

  • Las herramientas de desarrollo como los IDE y los analizadores de código pueden invocar el compilador desde el editor o crear herramientas que reduzcan significativamente el tiempo de compilación.

Las clases del compilador de Java están empaquetadas en el javax.toolspaquete. La ToolProviderclase de este paquete proporciona un método llamado getSystemJavaCompiler()que devuelve una instancia de alguna clase que implementa la JavaCompilerinterfaz. Esta instancia del compilador se puede utilizar para crear una tarea de compilación que realizará la compilación real. Los archivos fuente de Java que se van a compilar se pasarán a la tarea de compilación. Para esto, la API del compilador proporciona una abstracción de administrador de archivos llamada JavaFileManager, que permite recuperar archivos Java de varias fuentes, como el sistema de archivos, bases de datos, memoria, etc. En esta muestra, usamos StandardFileManagerun administrador de archivos basado en java.io.File. El administrador de archivos estándar se puede adquirir llamando al getStandardFileManager()método delJavaCompilerejemplo. El fragmento de código de los pasos mencionados anteriormente se muestra a continuación:

//Get an instance of java compiler JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); //Get a new instance of the standard file manager implementation StandardJavaFileManager fileManager = compiler. getStandardFileManager(null, null, null); // Get the list of java file objects, in this case we have only // one file, TestClass.java Iterable compilationUnits1 = fileManager.getJavaFileObjectsFromFiles("TestClass.java"); 

Opcionalmente, se puede pasar un escucha de diagnóstico al getStandardFileManager()método para producir informes de diagnóstico de cualquier problema no fatal. En este fragmento de código, pasamos nullvalores, ya que no recopilamos los diagnósticos de la herramienta. Para obtener detalles sobre los otros parámetros que se pasan a estos métodos, consulte la API de Java 6. El getJavaFileObjectsfromFiles()método de StandardJavaFileManagerdevuelve todas las JavaFileObjectinstancias que corresponden a los archivos fuente Java proporcionados.

Lee el resto de este articulo

Esta historia, "Análisis de código fuente usando las API de Java 6" fue publicada originalmente por JavaWorld.