viernes, 23 de marzo de 2012

Herramienta de construcción Gradle

Gradle
Gradle es una de las muchas herramientas que existen para construir proyectos de forma automatizada pero tiene unas cuantas ventajas sobre otras que se han estado utilizado ampliamente hasta el momento como Ant y Maven en el mundo Java.

Primero vamos a ver los problemas de Ant y Maven. El problema de Ant es que para definir las tareas a ejecutar para la construcción del proyecto se utiliza XML y usar XML para describir las acciones de las tareas da resultado ficheros grandes y de difícil mantenimiento en cuanto el problema de la construcción es complicado. Otro problema es que Ant no tiene la noción de dependencias por lo que tendremos que descargarlas una a una, si posteriormente actualizamos a una nueva versión tendremos que volver revisar manualmente las dependencias que tengamos. Usando Ant con Ivy puede superarse esa dificultad. Por otra parte si tenemos varios proyectos relacionados y que dependen unos de otros la construcción de los mismos con Ant quizá no sea la herramienta más adecuada a día de hoy. A parte de esos problemas con Ant tendremos la sensación no solo de estar programando nuestro proyecto sino también la herramienta para la construcción del mismo.

Maven trata de solucionar varios defectos de Ant. En él se pueden definir las dependencias de un proyecto y Maven se encargará de descargarlas de forma automática incluyendo las dependencias que tengan estas a su vez, es decir, realizando la obtención de las mismas de forma transitiva. Además por defecto establece una serie de convenciones en cuanto a estructura de carpetas y sin que al contrario de Ant tengamos que describirla. Pero el problema de Maven empieza cuando necesitamos personalizar nuestra construcción llegando incluso a ser peor que en el caso de Ant. Los plugins de Maven suelen estar poco y mal documentados y tratar de hacer lo que queremos puede ser frustante y una pérdida de tiempo.

Gradle tiene varias de las ventajas de ambos sin poseer ninguna de sus desventajas comentadas. Posee la personalización de Ant, y la automatización de dependencias y convenciones de Maven además de un mejor soporte para la construcción de varios proyectos relacionados. Un de las primeras diferencias es que en vez de XML utiliza Groovy, un lenguaje mucho más adaptado a la tarea. Si estamos acostumbrados a Ant la migración no nos será muy complicada ya que desde Gradle podremos usar las tareas de Ant pero de una forma más cómoda que en XML al usar Groovy como lenguaje pudiendo incluso llamar a targets definidos en archivos XML de Ant. Una de las pegas que tiene es que es un poco lento en su inicialización y tal vez para tareas que usamos mucho y necesitamos que se ejecuten rápido sea más adecuado definirlas en Ant (con la opción --daemon de Gradle se soluciona en gran medida). Con tan solo definir el siguiente archivo estaremos listos para construir un proyecto web Java, en este caso para un proyecto Tapestry que utilice Hibernate, Quartz, FreeMarker, Java Mail, Groovy, HtmlUnit y Mockito:

description = 'Tapestry Project'
version = '0.0.1'

apply plugin: 'eclipse'
apply plugin: 'java'
apply plugin: 'groovy'
apply plugin: 'war'

// Propiedades de configuración
//Eclipse
downloadJavadoc = true

// Java
sourceCompatibility = 1.6

repositories { 
 flatDir name: 'Local', dirs: 'misc/lib'
 mavenRepo name: 'Apache (Staging)', url: 'https://repository.apache.org/content/groups/staging/'
 mavenRepo name: 'JBoss', url: 'https://repository.jboss.org/nexus/content/repositories/releases/'
 mavenRepo name: 'Java', url: 'http://download.java.net/maven/2/'
    mavenCentral()
}

dependencies {
 compile 'org.apache.tapestry:tapestry5-annotations:5.3.2'
 compile 'org.apache.tapestry:tapestry-core:5.3.2'
 compile 'org.apache.tapestry:tapestry-beanvalidator:5.3.2'
 compile 'org.apache.tapestry:tapestry-hibernate-core:5.3.2'
 compile 'org.apache.tapestry:tapestry-hibernate:5.3.2'
 compile 'org.apache.tapestry:tapestry-func:5.3.2'
 compile 'org.apache.tapestry:tapestry-ioc:5.3.2'
 compile 'org.apache.tapestry:tapestry-javadoc:5.3.2'
 compile 'org.apache.tapestry:tapestry-jmx:5.3.2'
 compile 'org.apache.tapestry:tapestry-json:5.3.2'
 compile 'org.apache.tapestry:tapestry-test:5.3.2'
 compile 'org.apache.tapestry:tapestry-upload:5.3.2'
 compile 'org.apache.tapestry:tapestry-yuicompressor:5.3.2'

 compile 'org.hibernate:hibernate-core:3.6.8.Final'
 compile 'org.hibernate:hibernate-ehcache:3.6.8.Final'
 compile 'org.hibernate:hibernate-validator:4.2.0.Final'

 compile 'org.quartz-scheduler:quartz:2.1.0'
 compile 'org.freemarker:freemarker:2.3.18'
 compile 'org.apache.commons:commons-lang3:3.0'

 providedCompile 'javax.servlet:servlet-api:2.5'
 providedCompile 'javax.mail:mail:1.4.4'

 groovy 'org.codehaus.groovy:groovy-all:1.8.3'

 // Test
 testCompile 'junit:junit:4.8.2'
 testCompile 'net.sourceforge.htmlunit:htmlunit:2.9'

 testCompile 'org.mockito:mockito-all:1.9.0'
}

Incluyendo los plugins de gradle eclipse, java, groovy y war algunas de las tareas que disponemos son:

  • eclipse: Genera los archivos para poder importar el proyecto en eclipse incluyendo todas las dependencias del proyecto.
  • clean: limpia los archivos tenporales creados por gralde en la ejecución de las tareas.
  • classes: compila los archivos fuente de java, además haciendo uso del plugin de java tambien se compilan los archivos de codigo fuente de groovy.
  • javadoc: crea la documentación de javadoc de los archivos del proyecto.
  • jar: crea un jar con los archivos fuente de java.
  • war: crea un war del proyecto.

Para ver la estructura de directorios consultar la documentación de cada uno de los plugins:


La cantidad de plugins para gradle va en aumento. Algunos de los más útiles son: checkstyle, codenarc, pmd, tomcat, jetty.

Para instalarlo basta con descargar sus binarios, descompromirlos en una carpeta y crear una variable de entorno para $GRADLE_HOME. Una vez hecho esto su uso es similar al de ant y maven, nos colocamos en el directorio donde está el archivo .gradle y ejecutamos:

$GRADLE_HOME/bin/gradle [tarea]

Si queremos tener una experiencia de uso más agradable con gradle es muy útil usar su modo demonio ya que de otra manera tarda en cargarse bastantes segundos, si lo usamos cada poco tiempo y muchas veces aunque luego el tiempo de las propias tareas sea poco notaremos que perdemos tiempo esperando. Para evitarlo añadimos el parámetro --daemon, notaremos mucha diferencia respecto a lo se tarda en cargarse sin él y la ejecución de nuestras pequeñas tareas serán mucho más rápidas.

$GRADLE_HOME/bin/gradle --daemon [tarea]


La diferencia es notable de casi 12 segundos a casi 5, un poco menos de la mitad.

Referencia:
http://www.gradle.org/
http://www.gradle.org/current/docs/userguide/userguide.html
Usar Gradle mediante Gradle wrapper

http://ant.apache.org/
http://maven.apache.org/
http://ant.apache.org/ivy/