Eu sei que essa pode ser uma pergunta boba para programadores experientes. Mas eu tenho uma biblioteca (um cliente http) que alguns dos outros frameworks / jars usados em meu projeto requerem. Mas todos eles exigem diferentes versões principais, como:
httpclient-v1.jar => Required by cralwer.jar
httpclient-v2.jar => Required by restapi.jar
httpclient-v3.jar => required by foobar.jar
O carregador de classe é inteligente o suficiente para separá-los de alguma forma? Mais provável que não? Como o Classloader lida com isso, caso uma Classe seja a mesma em todos os três jars. Qual está carregado e por quê?
O Classloader só pega exatamente um jar ou mistura classes arbitrariamente? Portanto, por exemplo, se uma classe for carregada da versão 1.jar, todas as outras classes carregadas do mesmo carregador de classe irão para o mesmo jar?
Como você lida com esse problema?
Existe algum truque para de alguma forma "incorporar" os frascos no "required.jar" de forma que eles sejam vistos como "uma unidade / pacote" pelo Classloader
, ou de alguma forma vinculados?
fonte
Cada carga de classe escolhe exatamente uma classe. Normalmente, o primeiro encontrado.
OSGi tem como objetivo resolver o problema de várias versões do mesmo jar. Equinox e Apache Felix são as implementações de código aberto comuns para OSGi.
fonte
O Classloader carregará as classes do jar que estava no classpath primeiro. Normalmente, versões incompatíveis da biblioteca terão diferenças nos pacotes, mas no caso improvável, eles são realmente incompatíveis e não podem ser substituídos por um - tente jarjar.
fonte
Classloaders carregam classe sob demanda. Isso significa que a classe exigida primeiro por seu aplicativo e as bibliotecas relacionadas seriam carregadas antes de outras classes; a solicitação para carregar as classes dependentes é normalmente emitida durante o processo de carregamento e vinculação de uma classe dependente.
É provável que você encontre
LinkageError
s que indicam que definições de classe duplicadas foram encontradas para carregadores de classe. Normalmente, não tentam determinar qual classe deve ser carregada primeiro (se houver duas ou mais classes com o mesmo nome presentes no caminho de classe do carregador). Às vezes, o carregador de classe carrega a primeira classe que ocorre no caminho de classe e ignora as classes duplicadas, mas isso depende da implementação do carregador.A prática recomendada para resolver esse tipo de erro é utilizar um carregador de classe separado para cada conjunto de bibliotecas que possuem dependências conflitantes. Dessa forma, se um carregador de classe tentar carregar classes de uma biblioteca, as classes dependentes serão carregadas pelo mesmo carregador de classe que não tem acesso às outras bibliotecas e dependências.
fonte
Você pode usar o
URLClassLoader
for require para carregar as classes de uma versão diff-2 de jars:fonte