Estou usando o logback / slf4j para manipular o log em meu aplicativo. Tudo estava funcionando perfeitamente até que comecei a usar EJBs. Depois que adicionei um EJB sem estado ao meu aplicativo, o criador de logs começou a ignorar meu logback.xml e parou de usar meus appenders. Eu mudei para uma configuração de logger programático para ver o que estava errado e agora estou recebendo o seguinte erro quando tento usar meu logger dentro do EJB:
org.slf4j.impl.JDK14LoggerFactory cannot be cast to ch.qos.logback.classic.LoggerContext
Existe alguma configuração especial necessária para que o logback funcione com os EJBs? Se importa, estou implantando no glassfish v3.
Isso parece muito próximo ao problema descrito neste segmento e suspeito de um problema de carregamento de class semelhante. Devido à maneira como o logback.xml carrega o logback.xml (mais precisamente a forma como ele recupera um ClassLoader ), ele pode falhar ao pegar seu arquivo de configuração e retornar a BasicConfiguration padrão.
Não tenho certeza de como você empacota seu código, mas a solução sugerida é include o logback.xml em uma biblioteca EAR. Se você não estiver usando um pacote EAR, tente identificar o carregador de classs usado para ver onde colocar o arquivo logback.xml .
No final, isso pode ser um problema no logback. Não verifiquei o rastreador de problemas deles.
Atualização: Se você usar um pacote de guerra, tente configurar o GlassFish para usar primeiro os classloaders filho antes de delegar.No sun-web.xml :
Atualização: fiz um pequeno teste do meu lado e … não consigo reproduzir seu problema. Eu criei um projeto para um webapp Java EE 6 que possui a seguinte estrutura:
Eu também tentei com o EJB empacotado em seu próprio JAR e implementado no WEB-INF/lib e obter o mesmo resultado, ele simplesmente funciona. Você consegue identificar alguma diferença óbvia? Talvez faça o upload de uma versão simplificada do seu aplicativo (muito provavelmente será necessário para o relatório de bug BTW).
Estou executando o GlassFish v3 no Eclipse 3.5 (com o plugin GlassFish v3).
O org.slf4j.impl.JDK14LoggerFactory cannot be cast to ch.qos.logback.classic.LoggerContext exceção org.slf4j.impl.JDK14LoggerFactory cannot be cast to ch.qos.logback.classic.LoggerContext mostra que o SLF4J não está ligado ao logback-classic, mas ao slf4j-jdk14. Em suma, o código de log-in não é o culpado porque não está sendo exercitado nem chamado.
Parece que o GFv3 está exportando o slf4j-jdk14.jar para o seu aplicativo e, portanto, sobrescrevendo sua escolha do backend de logging, logback neste caso. Esse é um desses cenários em que o servidor de aplicativos, inadvertidamente, impõe suas opções ao usuário.
Se de fato o GFv3 impuser sua binding ao SLF4J no usuário final, então esse é um problema do GFv3 que deve ser resolvido pelos desenvolvedores do GFv3. Eu posso estar errado, mas acho que eles assumem que o usuário final não desejará nenhuma outra funcionalidade de log além do que é fornecido pelo java.util.logging e apenas empacota o slf4j-jdk14 no GFv3. Os usuários precisam contatá-los e reclamar que sua suposição está incorreta. Também é possível que eles estejam cientes desse problema e já forneçam uma solução alternativa …
Basicamente, o problema é que o servidor de aplicativos usa o slf4j AND, que suas tentativas de usá-lo vão para a binding slf4j do servidor de aplicativos, em vez daquele que você deseja.
Você não pode simplesmente usar a binding slf4j no Glassfish?
Aqui está praticamente o código relevante exato:
O Login EJB:
@Stateless @Interceptors(LoggingInterceptor.class) public class LoginEJB { @PersistenceContext(unitName = "persistence") private EntityManager em; public User getUser(String username) { try { Query query = em.createQuery("Select u from User u where u.userName = '" + username + "'"); User user = (User) query.getSingleResult(); return user; } catch (NoResultException e) { return null; } } }
@ManagedBean public class LoginBacking extends AbstractBacking { @NotEmpty(message = "User Name required.") private String username; @NotEmpty(message = "Password required.") private String password; @EJB private LoginEJB loginEJB; public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String performLogin() { String result = "login"; User user = loginEJB.getUser(username); if(null == user || !user.getPassword().equals(password)) { this.getFacesContext().addMessage("login-form:button-submit", new FacesMessage("The User Name or Password entered is incorrect.")); return result; } this.setCurrentUser(user); result = "success"; return result; } }
Eu tenho uma página jsf que tem
finalmente meu pom
4.0.0com.testtester1.0/version> Codewarmaven2-repository.dev.java.netJava.net Repository for Mavenhttp://download.java.net/maven/2/codecauscodehaushttp://repository.codehaus.orgibibliohttp://www.ibiblio.org/maven2/jbosshttp://repository.jboss.com/maven2truefalsejboss-snapshothttp://snapshots.jboss.org/maven2truetruejava.net.glassfishRepository hosting the jee6 artifactshttp://download.java.net/maven/glassfishjboss-pluginshttp://repository.jboss.com/maven2truefalsejboss-snapshot-pluginshttp://snapshots.jboss.org/maven2truetruejavax.facesjsf-api2.0providedjavax.servletservlet-api2.5providedjavax.elel-api1.0providedjavax.validationvalidation-api1.0.0.GAorg.glassfishbean-validator3.0-JBoss-4.0.0.Beta3org.glassfish.extrasglassfish-embedded-all3.0testjavaxjavaee-api6.0-SNAPSHOTjunitjunit4.7javax.facesjsf-api2.0providedorg.hibernatehibernate-core3.5.0-CR-2org.hibernatehibernate-annotations3.5.0-CR-2org.hibernatehibernate-commons-annotations3.2.0.Beta1org.hibernatehibernate-entitymanager3.5.0-CR-2org.hibernatehibernate-c3p03.5.0-CR-2postgresqlpostgresql8.4-701.jdbc4ch.qos.logbacklogback-core0.9.18ch.qos.logbacklogback-classic0.9.18org.slf4jslf4j-api1.5.11org.eclipse.persistencejavax.persistence2.0.0gfv3ee6org.apache.maven.pluginsmaven-compiler-plugin1.6 1.6org.apache.maven.pluginsmaven-war-plugin2.0org.apache.maven.pluginsmaven-war-plugin2.0
Edit: Eu também tentei mudar meu logger para uma estática, sem alteração.