Qual é o classpath padrão para EJBs?
-
29-09-2020 - |
Pergunta
Por favor, perdoe meu conhecimento lamentável de EJBs Java, mas, quando um EJB é implementado em um servidor de aplicativos como um arquivo .jar, coisas como Hibernate e log4j procuram primeiro seus arquivos de configuração (hibernate.cfg.xml e log4j.properties) em o arquivo .jar?
Solução
(...) quando um EJB é implementado em um servidor de aplicativos como um arquivo .jar, onde itens como Hibernate e log4j procuram primeiro seus arquivos de configuração (hibernate.cfg.xml e log4j.properties) no arquivo .jar?
Isso depende da implementação da ferramenta e não está relacionado ao fato de você estar usando EJBs.Para o Hibernate, a documentação escreve:
3.7.Arquivo de configuração XML
Uma abordagem alternativa para a configuração é especificar uma configuração completa em um arquivo nomeado
hibernate.cfg.xml
.Este arquivo pode ser usado como um substituto para ohibernate.properties
arquivo ou, se ambos estiverem presentes, para substituir as propriedades.O arquivo de configuração XML é por padrão, espera -se estar na raiz do seu
CLASSPATH
.
Em relação ao Log4J, o procedimento é descrito abaixo:
Procedimento de inicialização padrão
A biblioteca log4j não faz nenhuma suposição sobre seu ambiente.Em particular, não há anexos log4j padrão.Sob certas circunstâncias bem definidas, no entanto, o inializador estático do
Logger
A classe tentará configurar automaticamente o log4j.O idioma Java garante que o inicializador estático de uma classe seja chamado uma vez e apenas uma vez durante o carregamento de uma classe na memória.É importante lembrar que diferentes carregadores de classe podem carregar cópias distintas da mesma classe.Essas cópias da mesma classe são consideradas totalmente não relacionadas pela JVM.A inicialização padrão é muito útil em ambientes em que o ponto exato de entrada para o aplicativo depende do ambiente de tempo de execução.Por exemplo, o mesmo aplicativo pode ser usado como um aplicativo independente, como um applet ou como um servlet sob o controle de um servidor da Web.
O algoritmo exato de inicialização padrão é definido da seguinte forma:
- Configurando o
log4j.defaultInitOverride
A propriedade do sistema para qualquer outro valor "false" fará com que o LOG4J pule o procedimento de inicialização padrão (este procedimento).- Colocou o
resource
variável de string para o valor dolog4j.configuration
propriedade do sistema. A maneira preferida de especificar o arquivo de inicialização padrão é através dolog4j.configuration
propriedade do sistema. Caso a propriedade do sistemalog4j.configuration
não está definido e defina o recurso variável da string como seu valor padrão "log4j.properties".- Tente converter o
resource
variável para um URL.- Se a variável de recurso não puder ser convertida em um URL, por exemplo, devido a um
MalformedURLException
, então procure o recurso do caminho de classe ligandoorg.apache.log4j.helpers.Loader.getResource(resource, Logger.class)
que retorna uma URL.Observe que a string "log4j.properties" constitui um URL malformado.VerLoader.getResource(java.lang.String)
para a lista de locais pesquisados.- Se nenhum URL for encontrado, interrompa a inicialização padrão.Caso contrário, configure log4j a partir do URL.O
PropertyConfigurator
será usado para analisar o URL para configurar o log4j, a menos que o URL termine com a extensão ".xml", nesse caso aDOMConfigurator
será usado.Você pode opcional especificar um configurador personalizado.O valor dolog4j.configuratorClass
A propriedade do sistema é tomada como o nome da classe totalmente qualificado do seu configurador personalizado.O configurador personalizado que você especificar deve implementar oConfigurator
interface.
Para resumir, se você colocar os dois arquivos na raiz do seu EJB-JAR, eles deverão ser encontrados.
Em relação ao título da sua pergunta, sugiro ler Empacotando Aplicativos EJB 3 que estou citando abaixo:
Dependências entre módulos Java EE
Infelizmente, nenhuma especificação Java EE fornece um padrão para o carregamento de classe, e cada servidor de aplicativos implementa os carregadores de classe da maneira melhor para o fornecedor.No entanto, o Java EE define a visibilidade e o compartilhamento de classes entre diferentes módulos, e podemos representar a dependência entre diferentes módulos, como mostrado na Figura 4.
Conforme ilustrado na Figura 4, o carregador de classe da orelha carrega todos os frascos no diretório Lib que é compartilhado entre vários módulos.Normalmente, um único carregador de classe EJB carrega todos os EJB embalados em todos os módulos EJB-jar.O carregador de classe EJB é frequentemente o filho do carregador da classe de aplicativo e carrega todas as classes EJB.Como o EJB é uma criança do carregador de classe do ouvido, todas as classes carregadas no nível da orelha serão visíveis para os EJBs.
(fonte: desenvolvedor.com)Figura 4:Ilustração da visibilidade da classe de um arquivo de ouvido contendo vários módulos da Web, EJBS e módulos de biblioteca compartilhados.O carregador de classe da orelha carrega as classes nos frascos embalados como módulos da biblioteca e todas as classes carregadas pelo carregador de classe da orelha são visíveis para os EJBs.As classes carregadas pelo carregador de classe EJB são tipicamente visíveis para o módulo da Web na maioria dos contêineres, porque o carregador de classe de guerra é um filho do carregador de classe EJB.
Outras dicas
Eu acho que o log4j olharia em mais de um lugar para o arquivo log4j.properties.De qualquer forma, todos os arquivos de configuração em um EJB-Jar vão para dentro do diretório Meta-INV.