Dicas de programação. A idéia é ir postando as soluções dos problemas que enfrento diariamente no desenvolvimento de software. Como minha memória é muito volátil, essa é a maneira que encontrei de lembrar de como resolvi cada problema. Quem sabe, de quebra, não acabo ajudando outras pessoas?
quinta-feira, 20 de outubro de 2011
Log4j mistura logs entre as aplicações no Weblogic
Tenho um Web Service JWS executado em Weblogic 10.2 e seus logs estavam sendo misturados com outra aplicação web rodando no mesmo servidor.
Eu pensei que as aplicações foram totalmente independentes dentro do servidor, mas elas não são. Elas compartilham alguns classloaders. Veja imagem abaixo:
Esse problema ocorre porque o jog4j.jar é compartilhado entre as aplicações e isto ocorre porque ele é buscado do mesmo classloader.
Para resolver este problema, é necessário que cada aplicativo tenha o seu próprio log4j.jar dentro do .war. (ou .ear quando aplicável). É importante que todas as aplicações tenham seu próprio log4j. Se um deles não tiver, o problema vai continuar.
Além de ter o log4j.jar, também é necessário editar o weblogic-application.xml para avisar o Weblogic para usar as classes do log4j do classloader da aplicação.
Segue um exemplo de weblogic-application.xml:
<?xml version='1.0' encoding='UTF-8'?>
<weblogic-application xmlns="http://www.bea.com/ns/weblogic/90" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<prefer-application-packages>
<package-name>org.apache.log4j.*</package-name>
</prefer-application-packages>
</weblogic-application>
Se você estiver usando ant para construir o seu webservice JWS no Weblogic com a task jwsc, segue um trecho de build.xml que você pode usar para colocar o log4j no .war e usar um weblogic-application.xml personalizado.
No .war o log4j.jar deve ser colocado na pasta WEB-INF/lib e no .ear o weblogic-application.xml deve ser colocado na pasta META-INF.
<target name="jwsc" description="build web service">
<delete dir="${build.dir}"/>
<mkdir dir="${build.dir}"/>
<jwsc
srcdir="${webapp.dir}"
destdir="${build.dir}"
verbose="on" debug="on"
keepGenerated="no" >
<jws file="${jwsc.file}"
compiledWsdl="${jwsc.jws.compiledWsdl}"
contextPath="${jwsc.jws.contextPath}"
type="JAXWS" explode="false" >
</jws>
</jwsc>
<war destfile="${war.built}" update="true" >
<fileset dir="${webapp.dir}">
<include name="**/*.jar" />
</fileset>
</war>
<copy file="${service.src}/resource/weblogic-application.xml" todir="${build.dir}/META-INF/" overwrite="true" />
</target>
É importante que ${war.built} aponte para o ,war e o ${webapp.dir} aponte para a pasta com o fonte do webservice que possui pasta WEB-INF, que possui pasta lib, que possui log4j.jar.
Links:
http://download.oracle.com/docs/cd/E12840_01/wls/docs103/programming/classloading.html
https://forums.oracle.com/forums/thread.jspa?threadID=689458
http://www.coderanch.com/t/554020/Web-Services/java/adding-jar-files-building-war
http://ant.apache.org/manual/Tasks/war.html
quarta-feira, 19 de outubro de 2011
Por que o log4j não está logando?
Recentemente tive um problema com o mecanismo de log em um sistema que tive que dar manutenção.
Ele simplesmente estava ignorando a configuração log4j.properties e logava as mensagens com nível INFO.
Depois de algum tempo eu descobri que ele estava usando common-logging ao invés do log4j puro.
Não há nenhum problema em usar o commons-logging, ela funciona bem. O problema real era que apenas o commons-logging-api.jar e o log4j.jar foram incluídos no classpath. Estava faltando o commons-logging.jar.
Para suportar o log4j, o commos-logging precisa de dois jars no classpath: commons-logging e commons-logging-api.
Depois de adicionar o commons-logging.jar no classpath, o log4j.properties começou a ser lido e respeitado.
Leia mais sobre commons-logging aqui: http://commons.apache.org/logging/guide.html#Jars Included in the Standard Distribution
Assinar:
Postagens (Atom)