2008-11-05 9 views
6

Mi aplicación de servlet incluye varios archivos .jar de biblioteca, algunos de los cuales contienen archivos embedded log4j.xml o log4j.properties. ¡Me gustaría asegurarme de que log4j encuentre mi log4j.xml primero! He intentado buscar alguna especificación de las prioridades de los diversos elementos classpath en un servlet (p. Ej., ¿Las clases WEB-INF/preceden siempre a WEB-INF/lib?), O alguna forma de configurar o modificar el cargador de clase del servlet para que el directorio de recursos dado aparece temprano en el classpath. Hasta ahora, he dibujado un espacio en blanco. ¿Alguna sugerencia para garantizar que un archivo .war del servlet cargue el log4j.xml correcto a través del cargador de clases?Controlar el classpath en un servlet

Respuesta

4

Por lo que tengo entendido, la selección de recursos del classpath no es determinista (desde el punto de vista del desarrollador de la aplicación). Incluso si el mismo archivo se carga constantemente, el comportamiento podría cambiar: 1. Cuando actualice la versión de su contenedor actual. 2. Si cambia contenedores.

La solución más simple será eliminar los archivos de configuración de log4j incorporados desde los archivos de la biblioteca. Casi nunca es una buena idea insertar las configuraciones de log4j ya que conduce al problema que está viendo aquí ...

¿Son jarras o tarros de terceros que usted desarrolló?

+0

De terceros, de ahí el problema. –

+0

A riesgo de sonar despiadado, tal vez debería nombrarlos y avergonzarlos en la pregunta, y también presentar un error ... – johnstok

+0

Sugeriría eliminar manualmente el archivo de configuración log4j del jar de terceros. Sin embargo, esto será un dolor si usa maven, ivy, etc. para administrar dependencias. – johnstok

-1

Es necesario tener log4j.properties en su CLASSPATH. El mejor lugar es en WEB-INF/classes.

También debe asegurarse de utilizar su versión de log4j.jar. Por lo tanto, colóquelo en WEB-INF/lib, solo para asegurarse de que no está utilizando uno de las carpetas de tomcat, ya que puede causar problemas de carga de clases extrañas.

+0

que en realidad no responder a la pregunta que hice. ¿Está garantizado que WEB-INF/classes esté en el classpath antes de WEB-INF/lib? ¿Qué pasa si quiero que mi log4j.xml no esté en WEB-INF/classes sino en otro directorio? No es una clase después de todo. –

+0

Pero tiene que estar en classpath – Marko

3

We the Spring Log4jConfigListener en nuestro archivo web.xml.

Se puede especificar como un parámetro de contexto la ubicación del archivo de configuración de log4j, es decir, se podría configurar como /WEB-INF/log4j.xml

¿Esto sería una opción para usted? Si no está usando Spring, sé que puede establecer la ubicación de Log4j de forma programática, lo que también podría funcionar.

+0

La primavera no es una opción en este proyecto, pero es un consejo útil a tener en cuenta para el futuro, ¡así que gracias! –

1

En mi experiencia, WEB-INF/classes generalmente tiene prioridad sobre los archivos jar en WEB-INF/lib, sin embargo, eso también depende del contenedor de servlets que use (nunca pude averiguar el comportamiento de JRun, por ejemplo) . Sería de gran ayuda si pudieras decirme qué contenedor estás usando.

Además, ¿está seguro de que la configuración de log4j ofensiva está en un contenedor en WEB-INF/lib? Por lo general, cuando me he encontrado con problemas de ruta de clases en una situación contenedor de servlets, es a causa de las bibliotecas que residen fuera de la aplicación web.

Las especificaciones de servlets recomiendan que los cargadores de clases de aplicaciones web se cargan sus propias clases antes de delegar a cargador de clases del contenedor (SRV.9.7.2), pero ya que es contraria a la especificación de Java, no todos los vendedores hacen esto por defecto (de hecho, Tomcat es el único contenedor que he usado que hace esto por defecto). Dicho esto, siempre es posible configurar el comportamiento de carga de clase de su aplicación web del contenedor. Si me dices qué contenedor estás utilizando, puedo ayudarte (específicamente, lo he hecho antes con éxito en WebLogic, WebSphere, Glassfish y JRun)).

+0

Hola Jack, Actualmente estoy usando Tomcat 6 (tomcat6-6.0.18-1.1.fc9.noarch) y Jetty 6.1.11. Y no, no estoy del todo seguro de que el choque provenga de las configuraciones de log4j en mis .jars ... tenemos un comportamiento de registro extraño, y las configuraciones conflictivas parecen una buena hipótesis atm. –

+0

No he usado Jetty, pero en Tomcat, probablemente pueda descartar la configuración del cargador de clases como problema. ¿Está log4j.jar en su directorio WEB-INF/lib? –

1

Si no puede controlar la ruta de clase, como Tomcat la está configurando, ¿al menos puede establecer una propiedad del sistema para log4j.configuration? Creo que la ubicación señalada por esa propiedad se puede establecer fuera de la ruta de clases.

De lo contrario, otro enfoque, aunque desagradable, sería ejecutar explícitamente uno de los configuradores en el código de la aplicación.

15

Tomcat 8.5

Ditto Tomcat 8.0.

Ver documentación: Class Loader HOW-TO.

Tomcat 8.0

La respuesta es simple, tomado de la página de documentación de Tomcat, Class Loader HOW-TO. En particular, tenga en cuenta el uso del directorio/carpeta /WEB-INF/.

Por lo tanto, desde la perspectiva de una aplicación web, la clase o el recurso de carga se ve en los siguientes repositorios, en este orden:

  • clases de archivos de inicio de la JVM
  • /WEB-INF/classes de su aplicación web
  • /WEB-INF/lib/*.jar de su aplicación web
  • clases de cargador de clases Sistema (descrito anteriormente)
  • clase clases del cargador común (descrito anteriormente)

Si la aplicación cargador de clases Web es configured con <Loader delegate="true"/> entonces el orden se convierte en:

  • clases de archivos de inicio de la JVM
  • clases de cargador de clases del sistema (descritos arriba)
  • Clases comunes del cargador de clases (descrito anteriormente)
  • /WEB-INF/classes de su aplicación web
  • /WEB-INF/lib/*.jar de su aplicación web

Tomcat 6

Extraído de Tomcat página 6, Class Loader HOW-TO.

Por lo tanto, desde la perspectiva de una aplicación web, la clase o el recurso de carga se ve en los siguientes repositorios, en este orden:

  • clases de archivos de inicio de la JVM
  • clases de cargador de clases del sistema (descritos arriba)
  • /WEB-INF/classes de su aplicación web
  • /WEB-INF/lib/*.jar de su aplicación web
  • $CATALINA_HOME/lib
  • $CATALINA_HOME/lib/*.jar