2010-01-11 9 views
13

En mi proyecto Java estoy usando dos marcos de trabajo diferentes (digamos A.jar y B.jar) y ambos requieren un marco común (digamos Log4j.jar) pero en dos versiones diferentes. ¿Cómo es tratado por Java si el marco A necesita Log4J v1.1 y B necesita Log4j v1.2? ¿Causará algún tipo de conflicto/error o voluntad de algún modo (¿cómo?) Resuelto?¿Qué sucede cuando dos frameworks Java necesitan un tercero pero cada uno de los dos necesita una versión diferente de un tercero?

Si no causa conflicto/error (mi proyecto puede compilarse y ejecutarse) - ¿Puedo usar cualquier versión de Log4j en este proyecto? ¿O estoy obligado a seleccionar el número de versión inferior/superior de Log4j?

Actualización:Para ser más específicos ... ¿Qué pasa si alguna parte de la API Log4j cambió en v1.2 (digamos un único método doit() la firma cambió) y tanto A como B doIT llamada. ¿Qué pasará? ¿Se ejecutará mi proyecto? ¿Se bloqueará con el primer uso de doIt? ¿Qué versión de Log4j debo poner en classpath - v1.2 o ambas?

+0

No hay una respuesta general a esto, tendrás que ser más específico – skaffman

+0

@skaffman - ok, agregué más información y preguntas. .. – WildWezyr

Respuesta

3

Java no lo hace de forma nativa apoyar la gestión de múltiples versiones de la misma pieza de código , es decir, solo puede usar como máximo una versión dentro de la misma JVM (con el cargador de clases predeterminado).Sin embargo, la pregunta de salida 1705720, que tiene varias respuestas, señala las posibles formas de lograr eso (OSGi o cargadores de clase personalizados).

Pero dudo que valga la pena ya que el código no requiere varias versiones de log4j directamente. En su caso, le sugiero que empiece utilizando la versión más reciente de log4j (v1.2) primero y verifique si causaría algún problema para el marco A. Si causa conflicto, entonces retroceda a log4j v1.1 y verificar nuevamente Si realmente no tiene suerte, debe ensuciarse las manos ...

Actualización: para su descripción específica, no hay forma de usar log4j v1.1 o v1.2, como marco A y B cada uno requiere una firma diferente. Tienes que rodar tu propia versión de cualquiera de log4j o framework A, o B.

+0

¿Qué significa "no hay forma"? ¿Qué sucederá exactamente si lo intento? ¿No compilará? ¿Se bloqueará cuando se ejecute, al cargar o más tarde (en el primer uso intermedio del método doIt)? – WildWezyr

+2

dicen que coloque log4j-1.1.jar; log4j-1.2.jar en su ruta de clase en esa secuencia, se usará la clase (versión) de log4j-1.1.jar. la búsqueda de clase se detendría siempre que encuentre una. así que desde que se usa v1.1, cualquier código que espere la firma de log4j v1.2 tendría un problema (método no encontrado). – bryantsai

11

En un esquema de carga de clases planas, no hay soporte de versiones de bibliotecas. Necesita usar la versión más reciente de la biblioteca y eliminar otras versiones de la ruta de clases.

Algunos marcos, como OSGi, proporcionan mecanismos para manejar estos casos, pero no está claro que dependa de un marco de plugins.


Editar:

¿Qué pasa si alguna parte de la API Log4j cambió en v1.2 (digamos que un único método doIt() firma cambió) y tanto A como B llamada doIt. ¿Lo que sucederá? ¿Se ejecutará mi proyecto? ¿Se bloqueará al usar por primera vez doIt?

Una llamada que se basa en una firma que no está presente probablemente dará como resultado un NoSuchMethodError. Esto probablemente no sucederá hasta que se invoque el método. Se pueden producir otros errores si otros mecanismos dependen de la firma (por ejemplo, herencia de clase).

¿Qué versión de Log4j debo poner en classpath - v1.2 o en ambos?

Hacer dos versiones de una biblioteca en el classpath solo dará lugar a que un conjunto de clases se cargue al azar. El comportamiento no estará definido, pero podría dar lugar a todo tipo de errores y excepciones desagradables.

3

Si su elección de la suerte una versión de la jarra de terceros va a funcionar. Al final, se necesita un contenedor que comprenda y permita que todas las versiones de los componentes coexistan, algo así como OSGI.

0

Aunque no se recomienda pero puede usar ambas versiones. Coloque cada versión en un lugar donde solo ese marco pueda ver.

La solución óptima será conseguir las últimas versiones de ambos A y B, donde tanto el uso de las últimas bibliotecas comunes

+0

¿Cómo sugeriría uno podría lograr esto? – Buhb

+0

En teoría, podría hacer esto con algunas contorsiones manuales de ClassLoader; crear instancias de clases de A y B en cargadores de clases separados, que solo pueden ver la versión relevante de la biblioteca. En la práctica, sería tan molesto implementar y mantener que no es realmente * factible *. –

+0

Lo hice una vez usando un plugin Maven, no estoy seguro de qué era. No es tan complicado de hacer, pero como dije no es recomendable. Será un desastre para el desarrollador después de ti. – medopal

Cuestiones relacionadas