Creación: 30-05-2014
Índide de contenidos
1. Introducción
2. Entorno
3. Jetty de serie en Gradle
4. Plugin de Jetty de terceros
5. Plugin de Tomcat de terceros
6. Conclusiones
7. Sobre el autor
1. Introducción
Como ya vimos en el tutorial de instalación, Gradle es una herramienta para automatizar el proceso de construcción de software.
Cuando estamos construyendo aplicaciones Web es muy normal que queramos probar nuestra aplicación desplegándola en un servidor, pero este proceso suele ser cuando menos «tedioso» (prepara el paquete, copiarlo al servidor, arranca el servidor, …)
En este tutorial vamos a ver como podemos configurar Gradle para integrar un servidor Jetty o Tomcat en el propio proceso de construcción, de forma que sea Gradle el que se encargue de todas estas tareas.
Esto además tiene la ventaja adicional de que vamos a poder hacer despliegues en caliente, es decir, podemos cambiar el código, y sin necesidad de redesplegar o de reiniciar el servidor, veremos los cambios automáticamente.
2. Entorno
El tutorial está escrito usando el siguiente entorno:
- Hardware: Portátil MacBook Pro 15′ (2.3 GHz Intel i7, 16GB 1600 Mhz DDR3, 500GB Flash Storage).
- NVIDIA GeForce G7 750M
- Sistema Operativo: Mac OS X Lion 10.9.3
- Gradle 1.12
3. Jetty de serie en Gradle
Gradle ya tiene de serie un plugin de Jetty.
Para activarlo, nuestro fichero build.gradle
nos quedará de este estilo:
apply plugin: 'java' apply plugin: 'war' apply plugin: 'jetty' sourceCompatibility = 1.8 version = '1.0-SNAPSHOT' repositories { mavenCentral() } dependencies { providedCompile "javax.servlet:javax.servlet-api:3.0.1" } jettyRun { contextPath = '' scanIntervalSeconds = 2 }
Este plugin añade dos tareas al ciclo de vída de Gradle:
jettyRun
– Levanta un servidor Jetty en la dirección http://localhost:8080 usando los
ficheros que se encuentran en los directorios de fuentes del proyecto. Esto nos permite que si cambiamos estos ficheros veamos en caliente los cambios. ¡Ojo! si cambiamos ficheros.java
habrá que compilarlos en otro terminal congradle classes
.jettyRunWar
– Levanta el servidor igual que antes, pero esta vez lo que despliega es el.war
generado por el proyecto. Con esta opción perdemos la recarga de ficheros en caliente, pero nos permite probar el war, tal como queda después del proceso de compilación y empaquetado.
Este plugin permite cierta configuración de las tareas, para ver todos las posibilidades os recomiendo echar un vistazo a la documentación oficial, pero cabe destacar lo que hemos usado en el ejemplo:
contextPath
– Indica donde será accesible la aplicación, por defecto el nombre del war que se genera (ej. http://localhost:8080/nombre-war-1.0-SNAPSHOT). Como esto puede ser un poco incómodo, sobre todo si luego queremos lanzar pruebas automáticas, al dejarlo vacío''
la aplicación será accesible directamente en el raíz
(ej. http://localhost:8080/).scanIntervalSeconds
– Define cada cuanto tiempo tiene el servidor que comprobar si ha cambiado algún fichero para hacer la recarga en caliente. Su valor por defecto es0
por lo que no se hace el escaneo. Si queremos usarlo para desarrollo en conveniente ponerle un valor bajo para que no tengamos que esperar mucho 😉
El inconveniente de este plugin es que la versión de Jetty que usa es un poco antigua y por ejemplo no soporta Servlet 3.0. Además sus opciones de configuración también son bastante limitadas.
En el siguiente punto veremos cómo podemos mejorar estos inconvenientes.
4. Plugin de Jetty de terceros
Ya hemos dicho que el plugin que viene de serie con Gradle es un poco limitado, pero si buscamos un poco podemos encontrar el plugin jettyEclipse, de Andreas Sahlbach.
Este plugin sí permite usar la última versión de Jetty (v9 a día de hoy), además de muchas opciones de configuración y opciones de manejo, como por ejemplo reconstruir y recargar la aplicación web haciendo r + ENTER
(ya no necesitamos compilar en otro terminal).
Para configurarlo, nuestro fichero build.gradle
nos quedará de este estilo:
buildscript { repositories { jcenter() } dependencies { classpath (group: 'com.sahlbach.gradle', name: 'gradle-jetty-eclipse-plugin', version: '1.9.+') } } apply plugin: 'java' apply plugin: 'war' apply plugin: 'jettyEclipse' sourceCompatibility = 1.8 version = '1.0-SNAPSHOT' repositories { mavenCentral() } dependencies { providedCompile "javax.servlet:javax.servlet-api:3.0.1" } jettyEclipseRun { skipAnnotations = true }
En este caso sólo hay una tarea para lanzar el Jetty:
jettyEclipseRun
– Que, al igual que el plugin de serie, nos levante el Jetty en http://localhost:8080
Este plugin por defecto despliega la aplicación en el raiz /
. Y si usamos Jetty 8 o superior tendremos soporte para Servlet 3.0.
Dentro de la cantidad de opciones que tiene, podemos destacar la que hemos usado en el ejemplo:
skipAnnotations
– El valor por defecto de esta opción esfalse
. Si ponemos esta opción atrue
justo lo que conseguimos es que en el arranque de la aplicación no se haga el escaneo de las clases para ver si hay alguna que configura la aplicación. Esto es propio de Servlet 3.0, pero puede ser interesante desactivarlo para mejorar el tiempo
de arranque de la aplicación, que si es grandecita puede tardar un poco en escanear todos los paquetes y clases.
Especialmente útil cuando estamos en desarrollo, ya que si levantamos el servidor para probar algo queremos que tarde lo menos posible.
5. Plugin de Tomcat de terceros
Si lo que necesitamos es usar Tomcat, no tenemos soporte de serie en Gradle, pero fácilmente encontramos un plugin de Tomcat que nos da el servicio. Este plugin está construido por Benjamin Muschko.
Este plugin nos proporciona el manejo del pugin de serie de Jetty, junto con la potencia de configuración del plugin jettyEclipse. Así encontramos las tareas:
tomcatRun
tomcatRunWar
Ambas equivalentes a las que vimos al principio en el plugin de serie de Jetty.
Para usarlo nuestro fichero build.gradle
nos quedará del estilo:
buildscript { repositories { jcenter() } dependencies { classpath 'org.gradle.api.plugins:gradle-tomcat-plugin:1.2.3' } } apply plugin: 'java' apply plugin: 'war' apply plugin: 'tomcat' sourceCompatibility = 1.8 version = '1.0-SNAPSHOT' repositories { mavenCentral() } dependencies { providedCompile "javax.servlet:javax.servlet-api:3.0.1" def tomcatVersion = '7.0.45' tomcat "org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}" tomcat "org.apache.tomcat.embed:tomcat-embed-logging-juli:${tomcatVersion}" tomcat("org.apache.tomcat.embed:tomcat-embed-jasper:${tomcatVersion}") { exclude group: 'org.eclipse.jdt.core.compiler', module: 'ecj' } } tomcatRun { contextPath = '/' }
Vemos que la configuración es un poco más especial porque tenemos que declarar unas dependencias especiales con la función tomcat
. Mientras que en los casos anteriores sólo teníamos el javax.servlet-api
, que ni siquiera es obligatorio para el uso de ninguno de los plugins, pero sí recomendable si vamos a desarrollar una aplicación web.
6. Conclusiones
Podríamos decir que cualquiera de las versiones es buena, entonces ¿cuál elegir? Mi recomendación sería quedaos con la más pequeña que vuestro proyecto os permita, así, si no usamos Servlet 3.0, me quedaría con la que viene de serie ya que es la que tarda menos en arrancar.
¡Y ojo! que aunque hayamos visto cómo arrancar un servidor para hacer alguna prueba, no sería lo recomendable. Es mejor opción hacer test automáticos con jUnit ya que son infinitamente más rápidos. Si con estos tests no nos vale, levantaríamos el servidor y lanzaríamos tests automáticos contra este servidor, por ejemplo con SeleniumHQ.
Y recordad ¡evitar siempre los tests a mano!
Os he dejado un proyecto de prueba en GitHub por si queréis ver el código o cacharrear vosotros mismos. Tenéis los tres ficheros que hemos visto en el tutorial así que tenéis que ejecutar en la línea de comando para cada caso:
$ gradle --build-file jetty.gradle jettyRun
$ gradle --build-file jettyEclipse.gradle jettyEclipseRun
$ gradle --build-file tomcat.gradle tomcatRun
7. Sobre el autor
Alejandro Pérez García, Ingeniero en Informática (especialidad de Ingeniería del Software) y Certified ScrumMaster
Socio fundador de Autentia (Desarrollo de software, Consultoría, Formación)
mailto:alejandropg@autentia.com
Autentia Real Business Solutions S.L. – «Soporte a Desarrollo»