O que e JAR Hell?JAR Hell e um termo cunhado para descrever de forma genericas problemas relacionados ao ClassLoader. Suas variacoes mais comuns acontecem quando:Duas ou mais classes diferentes, com o exato mesmo nome qualificado acabam sendo incluidas no projeto (e.g, duas versoes diferentes da biblioteca ASM no Classpath).Duas ou mais bibliotecas no Classpath dependem de versoes diferentes das mesmas classes (e.g., Hibernate e Spring dependendo de versoes diferentes da biblioteca ASM).Sintomas do JAR HellJAR Hells possuem algumas peculiaridades marcantes, mesmo assim nem sempre seu diagnostico e obvio; varias vezes uma situacao de JAR Hell vem mixada com outros tipos de problemas como ausencia de dependencias transitivas no Classpath e omissoes em arquivos de configuracao.Eis alguns sintomas quem indicam um problema de JAR Hell:Estao sendo disparados NoSuchMethodError, NoSuchFieldError ou IllegalAccessError.ClassCastException entre classes iguais ou compativeis.Problemas de serializacao / deserializacao.Outra pista que aponta para uma situacao de JAR Hell acontece quando um ou mais dos problemas mencionados acontecem de forma intermitente, e particularmente quando dao a impressao de estarem relacionados a questoes de build / ambiente (e.g., aparecem no ambiente de homologacao mas nao no de desenvolvimento; builds pelo IDE funcionam / builds pela ferramenta de Integracao Continua nao; com o servidor em modo de desenvolvimento tudo funciona mas em modo de producao nao; com JVMs da Sun tudo funciona e com JRockit nao).Isso ocorre pois quando ha duas ou mais classes com o mesmo nome qualificado no Classpath, a logica que determina qual delas sera carregada fica codificada no ClassLoader utilizado, ou em ultima instancia, na logica dos ClassLoaders de base da propria JVM. Prever qual versao de uma classe sera carregada e uma tarefa dificil devido a cadeia complexa de ClassLoaders tipicamente presente em solucoes enterprise. O proprio ClassLoader escolhido para abrir determinada classe pode variar conforme o estado do container e codigo da aplicacao. Em geral o ClassLoader que carrega uma classe tambem fica responsavel por carregar todas as outras classes utilizadas por ela; essas classes e o valor de suas variaveis estaticas sao entao cacheados em memoria (e.g., na famigerada PermGen). Isso significa que - salvo excecoes em que o ClassLoader se torna elegivel para Garbage Collection e a JVM e otimizada para fazer unloading de classes - uma vez que determinada versao de uma classe seja carregada ela permanece em memoria, em um namespace relacionado ao ClassLoader, ate fim do processo.Resolvendo Problemas de JAR HellOs passos logicos para resolver JAR Hells sao:No caso de classes duplicadas dentro do dominio da sua aplicacao: Detectar e excluir versoes antigas da classe duplicada. Preferencialmente deixar somente uma classe de cada tipo no Classpath, i.e., nao ha necessidade da mesma classe estar presente em varios JARS da aplicacao, sendo recomendavel refatorar as classes repetidas para um JAR a parte.No caso de incompatibilidade entre bibliotecas de terceiros: Fazer upgrades e / ou downgrades das bibliotecas para uma combinacao com dependencias transitivas compativeis. Uma ferramenta para gerenciar dependencias ajuda muito.Se por algum motivo nao for possivel eliminar versoes duplicadas de uma classe ou encontrar bibliotecas compativeis, como ultimo recurso e possivel escrever ClassLoaders personalizados.