Problemas con el cargador de clases: cómo determinar qué versiones de la biblioteca (archivos jar) se cargan

StackOverflow https://stackoverflow.com/questions/139534

  •  02-07-2019
  •  | 
  •  

Pregunta

Acabo de resolver otro * yo-aunque-yo-estaba-usando-esta-versión-de-una-biblioteca-pero-aparentemente-mi-servidor-de-aplicaciones-ya-ha-cargado-un-mayor- problema de versión-de-esta-biblioteca- * (suspiro).

¿Alguien sabe una buena manera de verificar (o monitorear) si su aplicación tiene acceso a todos los archivos jar apropiados o versiones de clase cargadas?

Gracias de antemano!

[P.S. ¡Una muy buena razón para comenzar a usar la arquitectura del módulo OSGi en mi opinión!]

Actualización : Este artículo también ayudó ! Me dio una idea de qué clases cargó el cargador de clases de JBoss escribiéndolo en un archivo de registro.

¿Fue útil?

Solución

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

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

Otros consejos

Si tiene información de versiones apropiadas en un manifiesto jar, existen métodos para recuperar y probar la versión. No hay necesidad de leer manualmente el manifiesto.

java.lang.Package .getImplementationVersion () y getSpecificationVersion () y isCompatibleWith () suenan como si hicieran lo que estás buscando.

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

El javadoc para java.lang.Package no da los nombres de atributo de manifiesto específicos para estos atributos. Una búsqueda rápida en Google lo mostró en http: // java. sun.com/docs/books/tutorial/deployment/jar/packageman.html

En la versión actual de Java, el control de versiones de la biblioteca es un término bastante lanoso que se basa en que el JAR se empaqueta correctamente con un manifiesto útil. Incluso entonces, es mucho trabajo para la aplicación en ejecución reunir esta información de una manera útil. El tiempo de ejecución de JVm no te da ninguna ayuda.

Creo que su mejor opción es hacer cumplir esto en el momento de la compilación, utilizando herramientas de administración de dependencias como Ivy o Maven para obtener las versiones correctas de todo.

Es interesante que Java 7 probablemente incluya un marco de control de versiones de módulo adecuado para este tipo de cosas. No es que eso te ayude en este momento,

No creo que haya una buena manera 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: un EJB o una aplicación web buscará primero una clase o un recurso en las 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 principal, 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 aplicaciones que buscará en su propia ruta de clase.

Dicho esto, debe recordar que un módulo Java EE (web-app, ejb) siempre cargará las clases desde un jar que se encuentre en el ámbito más cercano. Por ejemplo, si empaqueta log4j v1 en el archivo war, log4j v2 al nivel del oído 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. quita eso y usará el que está al nivel del oído. sáquelo y usará el de classpath del servidor de aplicaciones. Las cosas se complican más cuando tiene dependencias complejas entre módulos.

Lo mejor es poner las bibliotecas globales de aplicaciones al nivel del oído.

Debe haber una mejor manera que la forma en que lo hago, pero tiendo a hacerlo de manera muy manual.

  1. Cada Jar debe tener su número de versión en el nombre del archivo (si no cambia su nombre).
  2. cada aplicación tiene su propia ruta de clase.
  3. Debe haber una razón para comenzar a usar un Jar actualizado (nueva versión). No solo cambie porque está disponible, cámbielo porque le brinda la funcionalidad que necesita.
  4. Cada lanzamiento debe incluir todos los tarros necesarios.
  5. Mantengo una clase de versión que conoce la lista de tarros que necesita (esto está codificado en el archivo fuente) y se puede verificar en tiempo de ejecución contra la lista de tarros en el classpath.

Como dije, es manual, pero funciona.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top