questões Classloader - Como determinar qual biblioteca versões (arquivos jar) são carregados

StackOverflow https://stackoverflow.com/questions/139534

  •  02-07-2019
  •  | 
  •  

Pergunta

Eu apenas resolvido outro * I embora-I-foi-usando-this-version-of-a-biblioteca-mas-aparentemente-my-app-server-se-já-carregado-an-older- versão-de-este-biblioteca-* questão (suspiro).

Alguém sabe uma boa maneira de verificar (ou monitor) se seu aplicativo tem acesso a todos os arquivos jar apropriados, ou de classe-versões carregadas?

Agradecemos antecipadamente!

[P.S. Uma boa razão para começar a usar o OSGi módulo de arquitetura na minha opinião!]

Atualizar : Este artigo ajudou bem ! Ele me deu uma visão que classloader aulas JBoss' carregado por escrevê-lo em um arquivo de log.

Foi útil?

Solução

Se acontecer de você estar usando JBoss, há um MBean (o repositório carregador de classe IIRC), onde você pode pedir para todos os carregadores de classe que tenha carregado uma certa classe.

Se tudo isso falhar, há sempre 'java -verbose: class'. Que irá imprimir a localização do frasco para cada arquivo de classe que está sendo carregado

Outras dicas

Se você tem informações versões apropriadas em um manifesto jar, existem métodos para recuperar e testar a versão. Não há necessidade de ler manualmente o manifesto.

java.lang.Package .getImplementationVersion () e getSpecificationVersion () e isCompatibleWith () soa como eles fariam o que você está procurando.

Você pode obter o pacote com this.getClass (). GetPackage (), entre outras formas.

O javadoc para java.lang.Package não dá os nomes de atributo de manifesto específicos para esses atributos. Uma busca rápida no Google transformou-se em http: // java. sun.com/docs/books/tutorial/deployment/jar/packageman.html

Na versão atual do Java, versão da biblioteca é um termo bastante lanoso que depende da JAR serem embalados corretamente com um manifesto útil. Mesmo assim, é um monte de trabalho para o aplicativo em execução para reunir estas informações de uma forma útil. O tempo de execução JVM lhe dá nenhuma ajuda.

Eu acho que sua melhor aposta é para fazer cumprir este em tempo de compilação, usando ferramentas de gerenciamento de dependência, como Ivy ou Maven para buscar as versões corretas de tudo.

Curiosamente, Java 7 provavelmente vai incluir um módulo apropriado de versão estrutura para precisamente esse tipo de coisa. Não que isso ajuda você a direita neste momento,

Eu não acho que há uma boa maneira de verificar isso. E eu não estou certo de que quer fazer isso. O que você precisa fazer é se familiarizar com a arquitetura de carregamento de classe do seu aplicativo de servidor, e entender como isso funciona.

Uma explicação simplificada de como ele funciona é: um EJB ou um web-app vai olhar primeiro para uma classe ou um recurso em bibliotecas declarou em seu próprio módulo (ejb-jar ou a guerra). se a classe não for encontrada lá, o carregador de classe encaminha o pedido para o carregador de sua classe pai que é ou uma dependência declarada (normalmente um EJB) ou o carregador de classe do aplicativo, que é responsável para bibliotecas e recursos de carga declarada no pacote de ouvido . Se a classe ou o recurso ainda não for encontrado o pedido é encaminhado para o servidor de aplicativo que irá procurar em seu próprio classpath.

Dito isto, você deve se lembrar que um módulo Java EE (web-app, EJB) sempre carregar classes de um frasco que está no escopo mais próximo. Por exemplo, se você pacote v1 log4j no arquivo de guerra, log4j v2 ao nível do ouvido e você colocar log4j v3 no caminho de classe do seu aplicativo de servidor, o módulo irá usar o frasco em seu próprio módulo. tirar isso e ele vai usar o ao nível do ouvido. levar isso para fora e ele vai usar aquele em classpath do aplicativo no servidor. As coisas ficam mais complicadas quando você tem dependências complexas entre os módulos.

Melhor é colocar bibliotecas globais de aplicação ao nível do ouvido.

Deve haver uma maneira melhor do que a maneira que eu faço, mas eu tendem a fazer isso de uma forma muito manual.

  1. Cada frasco deve tê-lo do número de versão no nome do arquivo (se ele não mudar de nome).
  2. cada aplicação tem seu próprio caminho de classe.
  3. Deve haver uma razão para começar a usar um Jar atualizado (nova versão). Não basta mudar, porque ele está disponível, a mudança porque lhe dá funcionalidade que você precisa.
  4. Cada versão deve incluir todos os frascos que são necessários.
  5. Eu mantenho uma classe versão que conhece a lista de Jars ele precisa (isto é codificado no arquivo de origem) e pode ser verificado em tempo de execução contra a lista de Jars no classpath.

Como eu disse, é manual, mas ele funciona.

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