Pergunta

Esse é um problema comum. Estou usando 2 bibliotecas A.Jar e B.Jar E estes dependem de diferentes versões do mesmo frasco.
Digamos que em tempo de execução eu preciso This.xxxjar

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

Eu posso compilar o frasco específico (A.jar/b.jar) contra sua dependência, mas em tempo de execução tenho que carregar apenas 1 versão. Qual deles?
Carregar apenas 1 dependência (a versão mais recente) significa que meu código provavelmente lançará exceções de tempo de execução se as bibliotecas não forem compatíveis com versões anteriores (existem bibliotecas compatíveis com versões anteriores?).

De qualquer forma, sei que algo como OSGI pode corrigir esse problema.
Estou me perguntando qual é a maneira antiga de corrigir esse tipo de problema ...

Muito obrigado

Foi útil?

Solução

"Antigo Way" que você mencionou (e o OSGI certamente usa sob o capô) é instalar seu próprio carregador de classe nas duas ramificações de suas dependências. É assim que, por exemplo, os servidores de aplicativos podem executar versões mais antigas e mais recentes do mesmo aplicativo dentro da mesma JVM.

Leia sobre a hierarquia de classe do carregador.

Na sua configuração, a parte complicada é o ponto articular, onde as classes de ambas as filiais se encontram. Nenhum dos ramos podem usar classes carregadas em outra. A maneira de fazê -lo funcionar é garantir que apenas as classes carregadas por classes de classe de inicialização (JRE Classes) ou Classloader do My.jar sejam transmitidas para as duas filiais.

Outras dicas

OSGI pode corrigir esse problema. Um pacote OSGI nada mais é do que um frasco com versões de detalhes adicionais de metadados. Um pacote possui um número de versão e detalhará os números de versão (ou intervalos) dos frascos dependentes.

Dar uma olhada em Este artigo introdutório de Javaworld Para maiores informações.

Para resolver isso sem OSGI, significa ter que garantir manualmente que você compila e executa com potes compatíveis. Como você descobriu, isso não é necessariamente uma tarefa trivial. Como os frascos não identificam necessariamente suas versões, a única maneira de fazer isso para gravar/comparar somas de verificação ou assinaturas.

Muitas bibliotecas são compatíveis com versões anteriores. Mas nem todos..


A maneira antiga é tentar depender de apenas uma versão.

Provavelmente é mais seguro compilar ambos com a mesma versão (mais recente).
Pelo menos você recebe erros de tempo de compilação, em vez de erros de tempo de execução.

Se necessário, você pode modificar um pouco sua biblioteca que funciona com a antiga dependência ...
Isso exigiria acesso à fonte ...


Observe que a compatibilidade com tempo de compilação também não garantirá o comportamento correto do tempo de execução. É um passo, então você pode:

  • Leia o arquivo WhatsNew para a nova versão do frasco
  • Veja a internet para usuários que relatam problemas de compatibilidade
  • Escreva Junits
  • Compare os códigos em ambos os potes

Conforme mencionado pelo KLE, a abordagem padrão é depender da versão mais recente. Não há garantia, mas na maioria das vezes isso funciona. Provavelmente, a melhor maneira (embora seja inchada) está usando o OSGI para superar isso.

Para referir uma compra de implementação básica de "Oldway" https://github.com/atulsm/elasticsearchClassloader

Isso fornece uma abordagem para lidar com versões compatíveis não backward do uso do cliente Elasticsearch.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top