Tomcat: error 404 aleatorio

El servidor de aplicaciones Tomcat (en este caso Tomcat 7) puede presentar un curioso error a la hora de acceder a una aplicación. Aleatoriamente, la aplicación puede presentar un error con código de salida «HTTP Status 404» (no encontrado), si acto seguido se recarga la página, el funcionamiento puede ser correcto con un código de salida «HTTP Status 200». El comportamiento no tiene por que ser tan continuado, depende de ciertos factores que veremos a continuación:

Muestra del comportamiento indicado:

192.168.1.100 - - [18/Sep/2014:18:47:42 -0500] "GET /foo HTTP/1.1" 200 -
192.168.1.100 - - [18/Sep/2014:18:48:03 -0500] "GET /foo HTTP/1.1" 404 5
192.168.1.100 - - [18/Sep/2014:18:48:07 -0500] "GET /foo HTTP/1.1" 404 5
192.168.1.100 - - [18/Sep/2014:18:48:09 -0500] "GET /foo HTTP/1.1" 200 -
192.168.1.100 - - [18/Sep/2014:18:48:32 -0500] "GET /foo HTTP/1.1" 404 5
192.168.1.100 - - [18/Sep/2014:18:48:34 -0500] "GET /foo HTTP/1.1" 200 -
192.168.1.100 - - [18/Sep/2014:18:50:34 -0500] "GET /foo HTTP/1.1" 404 5
192.168.1.100 - - [18/Sep/2014:18:50:37 -0500] "GET /foo HTTP/1.1" 200 -
192.168.1.100 - - [18/Sep/2014:18:50:46 -0500] "GET /foo HTTP/1.1" 404 5

El origen de este comportamiento está en la configuración de contextos (Context) en Tomcat, ya sea a nivel general o de una aplicación concreta. Existe una directiva aplicable a los contextos llamada «reloadable» que especifica si se monitoriza de forma continuada la aplicación en busca de cambios. Concretamente se revisan las clases de /WEB-INF/classes/ y /WEB-INF/lib. En el momento que se detecta un cambio, automáticamente se establece un reload de la aplicación. Esto provoca el error 404 mientras se vuelve a desplegar la aplicación.

Esta configuración (reloadable=»true») suele estar activa en entornos de desarrollo pero no es recomendable tenerla en producción.

La configuración se puede establecer en el archivo de configuración server.xml, dentro del container del Host y especificando el path de la aplicación a la que se va a aplicar:

      <Host name="localhost"  appBase="webapps"
 [...]
         <Context path="/foo"  reloadable="false" />
         <Context path="/bar"  reloadable="true" />
 [...]
    </Host>

No obstante, es recomendable aplicar estos contextos directamente por aplicación dentro de un archivo context.xml en su path de webapps, directorio META-INF:

webapps/foo/META-INF/context.xml

<Context path="/foo" reloadable="false" />

Tenéis toda la información sobre configuración de contextos (aplicaciones/webapps) en la documentación del sitio web de Tomcat.