2008-09-26 9 views
27

Me acaban de resolverse otra * I-aunque-me-me-usando-esto-version-of-a-biblioteca-pero-apparently- my-app-server-has-already-loaded-an-older-version-of-this-library- * issue (suspiro).cuestiones cargador de clases - Cómo determinar qué versiones (JAR-biblioteca de archivos) se cargan

¿Alguien sabe una buena manera de verificar (o monitor) si su aplicación tiene acceso a todos los archivos JAR-apropiadas o tipo-versiones cargadas?

¡Gracias de antemano!

[P.S. Una muy buena razón para empezar a utilizar el OSGi module architecture en mi opinión]

actualización: This artículo le ayudó también! Me dio una idea de qué clases cargó el cargador de clases de JBoss escribiéndolas en un archivo de registro.

Respuesta

18

Si está utilizando JBoss, hay un MBean (el repositorio del cargador de clases iirc) donde puede solicitar todos los cargadores de clases que han cargado una cierta clase.

Si todo lo demás falla, siempre hay '-verbose java: Clase' que imprimirá la ubicación de la jarra para cada archivo de clase que se está cargando.

+0

¡Parece algo que podría usar Tom! Voy a profundizar en eso mañana. Gracias de antemano ... Johan –

2

No creo que haya una buena forma de comprobarlo. Y no estoy seguro de que quieras hacer eso. Lo que debe hacer es familiarizarse con la arquitectura de carga de clases de su servidor de aplicaciones, y comprender cómo funciona.

Una explicación simplificada de cómo funciona es que un EJB o una aplicación web primero buscará una clase o un recurso en bibliotecas declaradas en su propio módulo (ejb-jar o war). si la clase no se encuentra allí, el cargador de clases reenvía la solicitud al cargador de clases padre que es una dependencia declarada (generalmente un ejb) o el cargador de clases de la aplicación que es responsable de cargar las bibliotecas y los recursos declarados en el paquete ear . Si aún no se encuentra la clase o el recurso, la solicitud se reenvía al servidor de la aplicación, que buscará en su propia ruta de clases.

Dicho esto, usted debe recordar que un módulo Java EE (web-app, EJB) siempre va a cargar las clases de un frasco que está en el ámbito más cercano. Por ejemplo, si empaqueta log4j v1 en el archivo war, log4j v2 en el nivel ear y coloca log4j v3 en la ruta de clase de su servidor de aplicaciones, el módulo usará el jar en su propio módulo. quítalo y usará el que está al nivel del oído. elimínalo y usará el que está en el classpath del servidor de aplicaciones. Las cosas se vuelven más complicadas cuando tienes dependencias complejas entre módulos.

Lo mejor es poner las bibliotecas globales de la aplicación a nivel del oído.

+0

Para JBoss, al menos, no es tan simple como eso. En algunos casos, JBoss cargará una clase desde * fuera * de su archivo WAR (por ejemplo, del servidor/predeterminado/lib) aunque la clase exista * dentro * de su archivo WAR. Depende de varios factores, como si la carga del ámbito está habilitada (el valor predeterminado varía según las versiones de JBoss) y si está habilitada la delegación en el repositorio de la clase principal. –

0

Tiene que haber una manera mejor que la forma en que lo hace, sino que tienden a hacer esto de una manera muy manual.

  1. Cada tarro debe tener su número de versión en el nombre del archivo (si no cambia su nombre).
  2. cada aplicación tiene su propio classpath.
  3. Debe haber un motivo para comenzar a utilizar un Jar actualizado (nueva versión). No solo cambie porque está disponible, cambie porque le brinda la funcionalidad que necesita.
  4. Cada versión debe incluir todos los Tarros necesarios.
  5. guardo una clase de versión que conoce la lista de las jarras que necesita (esto es codificado en el archivo de origen) y se puede comprobar en tiempo de ejecución con la lista de las jarras en la ruta de clase.

Como dije, es manual, pero funciona.

3

En la versión actual de Java, control de versiones de la biblioteca es un término bastante lana que se basa en el JAR siendo empaquetado correctamente con un manifiesto útil. Incluso entonces, la aplicación en ejecución necesita mucho trabajo para recopilar esta información de manera útil.El tiempo de ejecución de JVm no te ayuda en absoluto.

Creo que su mejor opción es aplicar esto en tiempo de compilación, utilizando herramientas de administración de dependencias como Ivy o Maven para buscar las versiones correctas de todo.

Curiosamente, Java 7 probablemente incluirá un marco de control de versiones de módulos adecuado para este tipo de cosas. No es que eso le ayude en este momento,

5

Si usted tiene versiones adecuadas información en un manifiesto jar, existen métodos para recuperar y poner a prueba la versión. No es necesario leer manualmente el manifiesto.

java.lang.Package .getImplementationVersion() y getSpecificationVersion() y isCompatibleWith() parecen que harían lo que estaba buscando.

Puede obtener el paquete con this.getClass(). GetPackage() entre otras formas.

el Javadoc para java.lang.Package no da los nombres de los atributos se manifiestan específicos para estos atributos. Una búsqueda rápida en Google lo subió al http://java.sun.com/docs/books/tutorial/deployment/jar/packageman.html

Cuestiones relacionadas