2009-10-12 17 views
19

Este es un problema común. Estoy utilizando 2 bibliotecas A.jar y B.jar y estas dependen de diferentes versiones del mismo contenedor.
Digamos que en tiempo de ejecución que necesito THIS.xxxjarJava Classloader: cómo hacer referencia a diferentes versiones de un jar

MY.jar 
    -> A.jar -> THIS.1.0.0.jar 
    -> B.jar -> C.jar -> THIS.5.0.0.jar 

puedo compilar el frasco específica (A.jar/B.jar) en contra de su dependencia, pero en tiempo de ejecución que he cargar sólo 1 versión. ¿Cúal?
Cargando solo 1 dependencia (la última versión) significa que mi código probablemente arrojará excepciones de tiempo de ejecución si las bibliotecas no son compatibles con versiones anteriores (¿hay bibliotecas compatibles con versiones anteriores?).

De todos modos, sé que algo como OSGi puede solucionar este problema.
Me pregunto cuál es la vieja manera de solucionar este tipo de problemas ...

Muchas gracias

+0

¿Es posible lograr esto? ¿Cómo OSGi ayuda? Estamos nuevamente introduciendo una depenencia en OSGi que es una sobrecarga en el desarrollo de software de producto típico (especialmente para incrustado) – sskumar86

Respuesta

7

La "forma anterior" que mencionaste (y la que OSGI sin duda usa debajo del capó) es instalar tu propio ClassLoader para ambas ramas de tus dependencias. Así es como, por ejemplo, los servidores de aplicaciones pueden ejecutar versiones más antiguas y nuevas de la misma aplicación dentro de la misma JVM.

Lea sobre la jerarquía del cargador de clases.

En su configuración, la parte difícil es el punto de unión, donde se encuentran las clases de ambas ramas. Ninguna de las ramas puede usar clases cargadas en otra. La forma de hacerlo funcionar es asegurarse de que solo las clases cargadas por el cargador de clases de arranque (clases JRE) o el cargador de clases de MY.jar se pasen a ambas ramas.

1

Muchas bibliotecas son compatibles con versiones anteriores. Pero no todos ..


La vieja manera es intentar depender de una sola versión.

Probablemente sea más seguro compilar ambos con la misma versión (más reciente).
Al menos se obtienen errores en tiempo de compilación, en lugar de errores de tiempo de ejecución.

Si es necesario, puede modificar un poco su biblioteca que funciona con la vieja dependencia ...
Esto requeriría el acceso a la fuente ...


Tenga en cuenta que la compatibilidad en tiempo de compilación tampoco garantizará el comportamiento correcto del tiempo de ejecución. Es un paso, a continuación, se puede:

  • leer el archivo WhatsNew para la nueva versión de la jarra
  • vistazo en Internet para los usuarios de informes de problemas de compatibilidad
  • JUnits escritura
  • comparar los códigos de both jar
4

OSGi puede solucionar este problema. Un paquete OSGi no es más que un contenedor con versiones de detalles de metadatos adicionales. Un paquete tiene un número de versión y detallará los números de versión (o rangos) de los jars dependientes.

Eche un vistazo a this introductory Javaworld article para obtener más información.

Resolver esto sin OSGi significa tener que garantizar manualmente que compile y ejecute con tarros compatibles. Como has descubierto, esa no es necesariamente una tarea trivial. Dado que las jarras no necesariamente identifican sus versiones, la única forma segura de hacerlo es registrar/comparar sumas de comprobación o firmas.

1

Según lo mencionado por KLE, el enfoque predeterminado es depender de la versión más reciente. No hay garantía, pero la mayoría de las veces esto funciona. Probablemente la mejor manera (aunque sea inflada) es usar OSGI para superarlo.

Cuestiones relacionadas