¿Tomcat carga el mismo archivo de biblioteca en la memoria dos veces si están en dos aplicaciones web?

Tengo dos aplicaciones en la carpeta tomcat/webapps .

 tomcat/webapps/App1 tomcat/webapps/App2 

Ambas aplicaciones comparten las mismas bibliotecas. Que se almacenan, por ejemplo, en tomcat/webapps/App1/WEB-INF/lib .

¿Las dos bibliotecas están cargadas dos veces en la memoria?

¿Debería poner estas bibliotecas compartidas en tomcat/server/lib ?

Como puede ver aquí , Tomcat crea un cargador de clases por aplicación web en su servidor. Por lo tanto, si tiene webapp1 y webapp2 que comparten la misma biblioteca, esta biblioteca se cargará dos veces.

Eventualmente puede colocar esta biblioteca en el directorio común (tomcat-dir / common / lib) si es compartida por todos los webapps que se ejecutan en su servidor Tomcat.

No recomendaría colocar los archivos jar en la carpeta compartida. Digamos, por ejemplo, que necesita en el futuro implementar una aplicación de terceros que tenga una versión más reciente de un archivo jar en la carpeta WEB-INF. Para esta aplicación, las clases del jar se cargarán dos veces (incluso si tienen los mismos nombres), una de la carpeta compartida y otra de la carpeta de la aplicación web. Esta situación puede causar errores muy difíciles de encontrar.

Si los archivos jar están en las carpetas de la aplicación web, entonces los cargan los cargadores de clases separados y no interfieren entre sí.

Por experiencia: las dos aplicaciones web están completamente aisladas entre sí – las bibliotecas para una no se utilizan en otra – por lo tanto, para responder a su pregunta inicial – sí, se cargarían dos veces.

Para responder a su segunda pregunta, si debe implementar estas bibliotecas en el directorio compartido de Tomcat, diría que no, y aquí está el motivo:

Si despliega una jarra de biblioteca en la ubicación compartida (tomcat / server / lib), esa versión de la biblioteca se convierte en la predeterminada para todas las aplicaciones web que se ejecutan bajo esa instancia de Tomcat. Como se puede ver en esta descripción general de la architecture de tomcat , el cargador de clases funciona “al final de la cadena”, con una carpeta de lib de la aplicación web individual como el último lugar donde se verá antes de arrojar una excepción de clase no encontrada. Esto no es cierto en Tomcat 6 y Tomcat 7: cualquier clase de la lib y la carpeta de clases de las aplicaciones web se resolverá antes que las comunes, y por lo tanto, esto no afectará a otras aplicaciones que implementen todos sus archivos jar en la guerra 2 .

El problema, por lo tanto, de implementar una biblioteca compartida en ese directorio es que rompe la architecture de las aplicaciones individuales que se aíslan unas de otras. Está bien en su ejemplo inicial, pero si desea implementar una aplicación de terceros (por ejemplo, si ejecuta una aplicación que consume Portlet para manejar contenido específico), se ejecuta al instante en los problemas de dependencia de la versión: su versión compartida de una biblioteca puede no es correcto para la aplicación de terceros, pero como el paquete ya está cargado, lanzará excepciones a la derecha y al centro.

Estamos usando tomcat6 y encontramos una buena manera de tener tomcat repleto de bibliotecas comunes que todas nuestras aplicaciones web necesitan.

Edite en conf / catalina.properties la entrada common.loader . Por ejemplo, agregue una carpeta adicional con tarros que le guste compartir ‘mylibs’

 common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar, ${catalina.home}/lib,${catalina.home}/lib/*.jar, {catalina.home}/mylibs/*.jar 

Luego ponga todas las bibliotecas comunes allí. Hecho.

¿Por qué comenzamos a usar una carpeta mylibs en lugar de WEB-INF / lib en todos los webapps (archivos WAR)?

¡El despliegue comenzó a ser una pesadilla después de que WAR cruzó la línea de los 50MB!

Cuando tenga una aplicación web con una versión nunca jar, puede ponerla en WEB-INF / lib para sobrescribir lo que tiene en mylibs .

Si no desea que sus bibliotecas se carguen dos veces, colóquelas en:

  • Tomcat 6: $CATALINA_HOME/lib
  • Tomcat 5: $CATALINA_HOME/common/lib

(eliminado de la pregunta y copiado aquí para que pueda ser votado / comentado)

PermGen Space of Heap se utiliza para almacenar clases y metadatos sobre clases en Java.

Error java.lang.OutOfMemoryError: PermGen espacio puede ocurrir con frecuencia porque estamos cargando muchas bibliotecas duplicadas en apache tomcat ¿alguien puede compartir al respecto en detalles