Sé que esta puede ser una pregunta tonta para los programadores experimentados. Pero tengo una biblioteca (un cliente http) que requieren algunos de los otros frameworks / jars utilizados en mi proyecto. Pero todos requieren diferentes versiones principales como:
httpclient-v1.jar => Required by cralwer.jar
httpclient-v2.jar => Required by restapi.jar
httpclient-v3.jar => required by foobar.jar
¿Es el cargador de clases lo suficientemente inteligente como para separarlos de alguna manera? ¿Probablemente no? ¿Cómo maneja esto el cargador de clases, en caso de que una clase sea la misma en los tres frascos? ¿Cuál está cargado y por qué?
¿El cargador de clases solo recoge exactamente un frasco o mezcla clases arbitrariamente? Entonces, por ejemplo, si una clase se carga desde la Versión-1.jar, ¿todas las demás clases cargadas desde el mismo cargador de clases irán todas al mismo jar?
¿Cómo maneja este problema?
¿Existe algún truco para "incorporar" de alguna manera los frascos en el "required.jar" para que sean vistos como "una unidad / paquete" por el Classloader
, o de alguna manera vinculados?
fuente
Cada carga de clase elige exactamente una clase. Por lo general, el primero que se encuentra.
OSGi tiene como objetivo resolver el problema de múltiples versiones del mismo jar. Equinox y Apache Felix son las implementaciones comunes de código abierto para OSGi.
fuente
Classloader cargará las clases del jar que estaba en la ruta de clases primero. Normalmente, las versiones incompatibles de la biblioteca tendrán diferencias en los paquetes, pero en un caso poco probable, son realmente incompatibles y no se pueden reemplazar con una: pruebe con jarjar.
fuente
Los cargadores de clases cargan la clase a pedido. Esto significa que la clase requerida primero por su aplicación y las bibliotecas relacionadas se cargaría antes que otras clases; la solicitud para cargar las clases dependientes se emite normalmente durante el proceso de carga y vinculación de una clase dependiente.
Es probable que encuentre
LinkageError
mensajes que indiquen que se han encontrado definiciones de clases duplicadas para los cargadores de clases, por lo general, no intentan determinar qué clase debe cargarse primero (si hay dos o más clases del mismo nombre presentes en la ruta de clases del cargador). A veces, el cargador de clases cargará la primera clase que ocurre en la ruta de clases e ignorará las clases duplicadas, pero esto depende de la implementación del cargador.La práctica recomendada para resolver este tipo de errores es utilizar un cargador de clases independiente para cada conjunto de bibliotecas que tengan dependencias en conflicto. De esa manera, si un cargador de clases intenta cargar clases desde una biblioteca, las clases dependientes serían cargadas por el mismo cargador de clases que no tiene acceso a las otras bibliotecas y dependencias.
fuente
Puede usar
URLClassLoader
for require para cargar las clases desde una versión diff-2 de jar:fuente