Esse e um topico avancado que fico devendo para um proximo post. Classifico o uso de ClassLoaders customizados como um ultimo recurso pois eles aumentam a Entropia do Software, sao de dificil manutencao e, se nao forem bem arquitetados, podem gerar todo tipo de problemas (NoClassDefFoundError, java.lang.OutOfMemoryError: PermGen space, etc).Encontrando classes duplicadasGeralmente essas classes estao em bibliotecas do EAR (APP-INF/lib), WAR (/WEB-INF/lib), ou do Servidor de Aplicacao.Para saber de que JAR / diretorio determinada classe esta sendo lida utilize os seguintes metodos:public static URL getLocation(Class clazz) { return clazz.getProtectionDomain().getCodeSource().getLocation();}public static URL getLocation(String className) throws ClassNotFoundException { return getLocation(Class.forName(className));}Exemplos de chamada e resposta (para um projeto mavenized):System.out.println(getLocation(EntityManager.class)); /* * file:/home/anthony/.m2/repository/javax/persistence/ * javax.persistence/2.0-SNAPSHOT/javax.persistence-2.0-SNAPSHOT.jar */System.out.println(getLocation( "org.apache.commons.lang.builder.ReflectionToStringBuilder")); /* * file:/home/anthony/.m2/repository/commons-lang/commons-lang/ * 2.6/commons-lang-2.6.jar */Um bom lugar a ser analisado sao clientes de Web services gerados automaticamente, principalmente quando mais de um servico depende do mesmo XSD. Nesse cenario e comum que varios clientes sejam gerados a partir de WSDLs diferentes, todos contendo suas proprias versoes da mesma classe. Na verdade todo tipo de codigo gerado automaticamente merece atencao: Classes JAXB geradas com xjc, entidades JPA repetidas em diferentes projetos EJB, etc. Problemas de compatibilidade entre bibliotecas de terceirosPara resolver esse tipo de JAR Hell e necessario encontrar versoes compativeis das bibliotecas (e.g., uma versao do Spring e do Hibernate que possam funcionar com a mesma versao da biblioteca ASM), ou, em casos de total incompatibilidade, escrever ClassLoaders customizados.Geralmente esse tipo de erro acontece com bibliotecas populares como como Apache Commons, Javassist e ASM que sao dependencias para uma grande quantidade de frameworks e bibliotecas.Devido a dependencias transitivas (e.g., seu projeto depende da biblioteca A que por sua vez depende da biblioteca B que depende da biblioteca C e assim sucessivamente), encontrar versoes compativeis de bibliotecas pode se tornar uma tarefa enfadonha. Para aliviar o trabalho do programador ferramentas poderosas como Maven, Ivy e Buildr estao disponiveis. Com essas ferramentas e possivel especificar as bibliotecas (e versoes / intervalos de versoes) que seu projeto necessita em arquivos de configuracoes; essas ferramentas fazem entao o download dos artefatos - e suas dependencias transitivas - a partir de uma hierarquia de repositorios de software (como o gigantesco Repositorio Central), ajustam o Classpath da aplicacao para compilacao / execucao / testes e ainda empacotam bibliotecas dentro dos EARs, WARs, etc para distribuicao quando cabivel. Caso ocorra algum conflito o desenvolvedor pode trocar facilmente a versao de determinada biblioteca no arquivo de configuracao e deixar que a ferramenta faca o trabalho duro por ele.Enquanto uma ferramenta como o Maven nao se aplica a todo tipo de projeto (pois introduz suas proprias complexidades), eu costumo usa-lo pelo menos para fazer download das dependencias do projeto e exporta-las com o Dependency plugin. Fico devendo um tutorial sobre esse assunto para um proximo post.Bibliotecas do Servidor de Aplicacao vs Bibliotecas do ProjetoPessoalmente tento, sempre que possivel, usar bibliotecas do proprio servidor (que passaram por todo o processo de homologacao do Java EE, e, por via de regra - mas nao como verdade absoluta - sao compativeis). Para esclarecer, nao estou pedindo para ninguem abrir mao