gui example español java classloader

example - java ui



Java classloaders: ¿por qué buscar primero el class classer principal? (6)

El cargador de clases de la aplicación web de Tomcat no obedece a "usar el padre primero". Como se menciona en los docs :

Como se mencionó anteriormente, el cargador de clases de aplicaciones web difiere del modelo de delegación de Java predeterminado (de acuerdo con las recomendaciones en la Especificación de Servlet, versión 2.4, sección 9.7.2 Cargador de clases de aplicaciones web). Cuando se procesa una solicitud para cargar una clase desde el cargador de clases WebappX de la aplicación web, este cargador de clases buscará primero en los repositorios locales, en lugar de delegar antes de mirar. Hay excepciones. Las clases que forman parte de las clases base de JRE no se pueden anular.

El comportamiento correcto para un cargador de clases en Java es:

  1. Si ya ha sido cargado, devuelve la clase.
  2. Llame a la clase de carga padre ()
  3. Intenta y carga la propia clase.

Por lo tanto, la clase definida en el classpath del sistema siempre debe cargarse primero. Tomcat define el cargador de clases por war, que tiene el cargador de clases del sistema como principal, por lo que si intenta cargar una clase, primero buscará en la ruta de clases del sistema y luego en la ruta de clases definida en el archivo war.

Según mi entendimiento, esto es por dos razones:

  1. Para evitar problemas con diferentes versiones de las clases que se utilizan. Imagina que redefiní java.lang.Object en una guerra, sería una pesadilla.
  2. Para evitar dependencias en los cargadores de clases secundarios: el cargador de clases del sistema no puede depender de los cargadores de clases secundarios: sería difícil volver a desplegar una guerra, por ejemplo.

Entonces, la pregunta es:

Además de los problemas anteriores, ¿existen otras fallas en la implementación de un cargador de clases que no realice una búsqueda principal primero?


La única otra razón que se me ocurre sería asegurar que el classpath funcione como se esperaba. Al buscar primero en el padre, en efecto, está colocando la ruta de clase del padre (es decir, la ruta de clase del sistema) antes de la ruta de clase del hijo. Por lo tanto, si especifica jars específicos cuando inicia el jvm usando -cp, estos "sombrearán" cualquier tarro que haya incluido en cualquier archivo que esté intentando cargar. Si no verifica primero al padre, entonces la ruta de la clase del niño podría sombrear al padre.


Si no busca a su padre, perderá el acceso a todos los objetos estándar de Java y es probable que no pueda ejecutarse en absoluto.

Pero es razonable buscar primero en su propio cargador de clases, antes de intentar con el padre. Si desea anular el comportamiento que proporciona una clase por encima de usted, deberá hacerlo de esta manera.

La JVM no lo hace, porque buscar a tu padre primero tiene más sentido. Sin embargo, si sabes lo que estás haciendo, puedes hacer cosas bastante interesantes con los cargadores de clases. Echa un vistazo a Classworlds .


Tarlog es correcto, no tienes que hacerlo de esa manera. Java no imaginó un caso de uso como Tomcat.

Sin embargo, es cuestionable por qué los contenedores alojan múltiples aplicaciones en una máquina virtual. Procesos separados es mejor


Tomcat no busca primero un cargador de clases padre. En realidad, hace lo contrario: primero se ve en la aplicación web y luego se dirige al cargador de clases principal (que es "lib" para Tomcat 6/7 y "compartido" para Tomcat 5.5). La excepción para esta regla son las clases del sistema (creo que todo lo que tiene el paquete java. * Y javax. *), Estas clases se buscaron solo en el cargador de clases del sistema. Creo que la razón por la que lo hacen es la razón # 1 que usted declaró.

Así que básicamente está bien implementar la estrategia de los padres primero. También está bien implementar padre-último. Ambas estrategias tienen sus contras y pros.

Te daré una razón más, la de implementar primero el padre: reduces la cantidad de clases cargadas en la memoria permanente. Imagina que tienes varias aplicaciones web utilizando la misma biblioteca. Con los padres primero se carga la biblioteca una vez. Con parent-last se cargará varias veces.
Sin embargo, con Parent-first se requerirá que todas las aplicaciones web utilicen la misma versión de la biblioteca, mientras que con Parent-last pueden usar versiones diferentes.