Ultima revisión 15/11/2014
Edición en caliente con Eclipse, Apache Tomcat y JSF
Cuando un proyecto se encuentra en una etapa de desarrollo u optimización, a menudo es necesario realizar muchos cambios pequeños, algunos de los cuales son meramente pruebas para comprobar el buen funcionamiento de los algoritmos. Si estamos en plataformas de tipo PHP, el siguiente problema no lo veréis nunca pero, si estáis trabajando con Eclipse y Apache Tomcat, seguro que en alguna ocasión, os encontraréis u os habreis encontrado con que cada vez que hacéis un cambio en los contenidos estáticos tales como CSS o JS, tenéis que hacre un ReLoad de toda la apliacación. Me imagino lo que estáis pensando, esa forma de trabajar no es factible, ni eficiente, ni lógica.
¿Entonces?, ¿cómo nos enfrentamos al problema de la recarga o reinicio constante?. Pues bien, para abordar esta cuestión, lo primero es estar bien seguro de que la variable PROJECT_STAGE está en modo Development. Para ello, debéis ir al archivo web.xml y buscar esta propiedad.
Cambiar el modo de contexto de PROJECT_STAGE
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
Ajustar el componente de facelets
Para que esto funcione es necesiario que se compruebe que el complemento Facelets está activado en la configuración JRebel y poner el siguiente código en el web.xml:
<context-param>
<param-name>javax.faces.facelets.DEVELOPMENT</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>javax.faces.facelets.REFRESH_PERIOD</param-name>
<param-value>1</param-value>
</context-param>
Ajustar el PermGem Space
Una de las cosas que más me ha llamado la atención de Eclipse es que utiliza muchísima memoria y, eso conlleva que, de vez en cuando, no se nos desplieguen las aplicaciones, se detengan o incluso que no podamos editar cambios en caliente (que es el problema que nos atañe).
Efectivamente, según sea de grande el proyecto, así nos iremos quedando sin memoria y se provocarán fallos de OutOfMemory. Para solucionar esto basta con modificar unos cuantos valores del archivo config.ini (dentro de la carpeta del eclipse), lo cuales, hacen referencia a PermSize y tamaño de la memoria: por ejemplo,
-XX:MaxPermSize=1024m
-Xms512m
-Xmx4096m
El parámetro MaxPermSize viene por defecto con 64MB y es el que debemos cambiar a un valor suficiente. Un ejemplo podría ser un valor de 1024MB para proyectos medianamente grandes y 256MB si son pequeños. Los otros 2, son el mínimo y máximo de memoria disponibles y que, según he visto, la recomendación es un mínimo de 512MB y, para conocer el valor máximo, re recomienda añadir la opción -XX:+PrintFlagsFinal e iniciar el Tomcat para conocer el valor a través de la consola y, en dónde veremos un línea parecida a:
uintx MaxHepSize :=3273841824
Visto este valor, estableceremos un valor de -Xmx un poco mayor para conseguir que vaya fluido.
Ajustes en caliente a través de Reloadable
Tomcat incluye un método llamado backgroundProcess como parte del componente de Catalina. Normalmente, este proceso ofrece sesiones de caducidad, pero cuando se configura correctamente, también puede gestionar los recursos de una aplicación para comprobar si hay cambios y, si es así, pedir una recarga al instante.
Para configurar esta "recarga" sólo hay que agregar el atributo "reloadable" al elemento de Context de la aplicación, ya sea en su fragmento de contexto o en server.xml:
<Context ... reloadable="true">
También es posible configurar el retardo en segundos antes de que el backgroundProcess se ejecute en el contenedor del elemento de contexto, a través del atributo backgroundProcessorDelay, pero, hay que tener cuidado porque, este valor también puede ser heredado desde el Host y, una modificación no controlada, puede causar comportamientos no deseables.
Actualización en caliente a través de WatchedResource
Cuando se define un contexto como reloadable, el comportamiento por defecto de Catalina es observar sus clases, bibliotecas y archivos de configuración del archivo web.xml para que los cambios provoquen la recarga automática. En multitud de ocasiones, desearás añadir otros archivos a esta lista, como los archivos de configuración del Log o CSS. En estas situaciones, puede utilizar el elemento WatchedResource anidado dentro del contexto para especificar los archivos adicionales en los que Tomcat debe estar escuchando. Para ello podemos utilizar la siguiente sintaxis:
<Host>
<Context ... reloadable="true">
<WatchedResource>path/to/watched/resource</WatchedResource>
<WatchedResource>another/path/to/another/resource</WatchedResource>
</Context>
</Host>
Como se aprecia en el ejemplo, cada WatchedResource contiene un recurso o archivo. Para configurar estas opciones se puede hacer desde el context.xml de la aplicación, desde el server.xml o, desde el archivo conf/context.xml de Catalina si lo que se desea es una crear una configuración global para todos los contextos.