使用EJB3.1进行logback [英] logback with EJB3.1

查看:82
本文介绍了使用EJB3.1进行logback的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用logback / slf4j来处理我的应用程序中的日志记录。在我开始使用EJB之前,一切都很完美。一旦我将无状态EJB添加到我的应用中,记录器就开始忽略我的logback.xml并停止使用我的appender。我切换到编程记录器配置,看看有什么不对,现在当我尝试在EJB中使用我的记录器时,出现以下错误:


org.slf4j.impl.JDK14LoggerFactory不能转换为ch.qos.logback.classic.LoggerContext



< 来源于行:

$ p $ LoggerContext lc =(LoggerContext)LoggerFactory.getILoggerFactory();



是否有任何必要的特殊配置让logback与EJB一起工作?如果有问题,我将在glassfish v3上进行部署。 解决方案

这看起来非常接近这个线程,我怀疑类似的类加载问题。由于logback加载 logback.xml (更准确地说,它检索 ClassLoader 这样做的方式),它会可能在拾取其配置文件时失败并回退到默认的 BasicConfiguration



不知道如何打包代码,但建议的解决方法是在EAR库中包含 logback.xml 。如果您未使用EAR包装,请尝试确定用于查看放置 logback.xml 文件的类加载器。

最后,这可能是logback中的一个问题。虽然没有检查他们的问题跟踪器。



更新:如果您使用战争包装,请尝试配置GlassFish以便首先使用子类加载器在委托之前。在 sun-web.xml中

 < sun-web -app> 
< class-loader delegate =false/>
< / sun-web-app>


$ b




更新:我在我身边进行了一些测试,并且...我无法重现您的问题。我为Java EE 6 webapp创建了一个具有以下结构的项目:

 
$树示例
示例
| - pom.xml
` - src
` - main
| - java
| ` - com
| ` - stackoverflow
| ` - q2418355
| | - SimpleEJB.java
| ` - SimpleServlet.java
| - 资源
| ` - logback.xml
` - webapp
| - META-INF
| ` - MANIFEST.MF
| - WEB-INF
| ` - lib
` - index.jsp

我的pom.xml如下所示:

 <?xml version =1.0encoding =UTF-8?> 
< project xsi:schemaLocation =http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd
xmlns =http://maven.apache.org/POM/4.0.0xmlns:xsi =http://www.w3.org/2001/XMLSchema-instance>
< modelVersion> 4.0.0< / modelVersion>
< groupId> com.stackoverflow.q2418355< / groupId>
< artifactId>样本< / artifactId>
< version> 1.0-SNAPSHOT< / version>
<包装>战争< / packaging>
< name>示例Maven Webapp< / name>
< url> http://maven.apache.org< / url>
<依赖关系>
< dependency>
< groupId> javax< / groupId>
< artifactId> javaee-api< / artifactId>
< version> 6.0< / version>
< scope>提供< / scope>
< /依赖关系>
< dependency>
< groupId> junit< / groupId>
< artifactId> junit< / artifactId>
< version> 4.7< / version>
< scope> test< / scope>
< /依赖关系>
< dependency>
< groupId> ch.qos.logback< / groupId>
< artifactId> logback-classic< / artifactId>
< version> 0.9.18< / version>
< /依赖关系>
< dependency>
< groupId> org.slf4j< / groupId>
< artifactId> slf4j-api< / artifactId>
< version> 1.5.11< / version>
< /依赖关系>
< /依赖关系>
< build>
< plugins>
< plugin>
< groupId> org.apache.maven.plugins< / groupId>
< artifactId> maven-compiler-plugin< / artifactId>
< version> 2.0.2< / version>
<配置>
< source> 1.6< / source>
< target> 1.6< / target>
< / configuration>
< / plugin>
< plugin>
< groupId> org.apache.maven.plugins< / groupId>
< artifactId> maven-war-plugin< / artifactId>
< version> 2.1-beta-1< / version>
<配置>
< failOnMissingWebXml> false< / failOnMissingWebXml>
< / configuration>
< / plugin>
< / plugins>
< finalName>样本< / finalName>
< / build>
< / project>

SimpleEJB.java 的代码是:

  package com.stackoverflow.q2418355; 

import javax.ejb.Stateless;

导入org.slf4j.Logger;
导入org.slf4j.LoggerFactory;

@Stateless
public class SimpleEJB {
private static Logger logger = LoggerFactory.getLogger(SimpleEJB.class);

public String sayHello(String name){
logger.debug(>> sayHello());
logger.debug(<<< sayHello());
返回Hello+名字+!!!;


SimpleServlet的代码。 java 是:

  package com.stackoverflow.q2418355; 

import java.io.IOException;
import java.io.PrintWriter;

import javax.ejb.EJB;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(urlPatterns = {/ SimpleServlet})
公共类SimpleServlet扩展HttpServlet {
@EJB
SimpleEJB bean;

private static Logger logger = LoggerFactory.getLogger(SimpleServlet.class);
$ b @Override
public void doGet(HttpServletRequest request,HttpServletResponse response)throws IOException {
logger.debug(>> doGet());
PrintWriter out = response.getWriter();
out.println(< html>< body>);
out.println(< h2> Serving at:+ request.getContextPath()+< / h2>);
out.println(< h2> Invoking EJB:+ bean.sayHello(Duke)+< / h2>);
out.println(< / body>< / html>);
logger.debug(<< doGet());


index的代码。 jsp 是:

 < html> 
< body>
< h2> Hello World!< / h2>
通过点击< a href =SimpleServlet>在这里< / a>来调用Servlet。
< / body>
< / html>

我的 logback.xml 看起来像:

 <配置> 
< appender name =STDOUTclass =ch.qos.logback.core.ConsoleAppender>
< layout class =ch.qos.logback.classic.PatternLayout>
<模式>%d {HH:mm:ss.SSS} [%线程]%-5级别记录器{36} - %msg%n< / Pattern>
< / layout>
< / appender>

< appender name =FILEclass =ch.qos.logback.core.FileAppender>
< File> /tmp/logs/testFile.log< / File>
<追加>真< /追加>

< layout class =ch.qos.logback.classic.PatternLayout>
< Pattern>% - 4relative [%thread]%-5level%logger {35} - %msg%n< / Pattern>
< / layout>
< / appender>

< logger name =com.stackoverflow.q2418355level =TRACE/>

< appender-ref ref =STDOUT/>
< appender-ref ref =FILE/>
< / root>
< / configuration>

我的 logback.xml 当调用servlet时,我得到了以下跟踪(从我的日志文件中获取):

  10913 [http-thread-pool-8080 - (1)] DEBUG com.stackoverflow.q2418355.SimpleServlet  - >> doGet()
10928 [http-thread-pool-8080-(1)] DEBUG com.stackoverflow.q2418355.SimpleEJB - >> sayHello()
10928 [http-thread-pool-8080-(1)] DEBUG com.stackoverflow.q2418355.SimpleEJB - << sayHello()
10932 [http-thread-pool-8080-(1)] DEBUG com.stackoverflow.q2418355.SimpleServlet - << doGet()

我也尝试将EJB打包在自己的JAR中,并部署在 WEB-INF / lib 并得到相同的结果,它只是起作用。你能发现任何明显的差异吗?也许上传一个简化版本的应用程序(很可能需要为bug报告BTW)。

我在Eclipse 3.5下运行GlassFish v3(使用GlassFish v3插件)。


I am using logback/slf4j to handle logging in my application. Everything was working perfectly until I started using EJBs. Once I added a stateless EJB to my app, the logger started ignoring my logback.xml and stopped using my appenders. I switched to a programmatic logger configuration to see what was wrong and now I am getting the following error when I try to use my logger within the EJB:

org.slf4j.impl.JDK14LoggerFactory cannot be cast to ch.qos.logback.classic.LoggerContext

stemming from the line:

LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();

Is there any special configuration necessary to get logback to work with EJBs? If it matters I am deploying on glassfish v3.

解决方案

This looks very close to the problem described in this thread and I suspect a similar class loading issue. Because of the way logback loads logback.xml (more precisely the way it retrieves a ClassLoader to do so), it may fail at picking up its configuration file and fall back on a default BasicConfiguration.

Not sure how you package your code but the suggested workaround is to include the logback.xml in a EAR lib. If you aren't using an EAR packaging, try to identify the class loader used to see where to put the logback.xml file.

At the end, this might be a problem in logback. Didn't check their issue tracker though.

Update: If you use a war packaging, try to configure GlassFish to use firstly the child classloaders before to delegate. In the sun-web.xml:

<sun-web-app>
  <class-loader delegate="false"/>
</sun-web-app>


Update: I did a little test on my side and... I cannot reproduce your problem. I've created a project for a Java EE 6 webapp which has the following structure:

$ tree sample
sample
|-- pom.xml
`-- src
    `-- main
        |-- java
        |   `-- com
        |       `-- stackoverflow
        |           `-- q2418355
        |               |-- SimpleEJB.java
        |               `-- SimpleServlet.java
        |-- resources
        |   `-- logback.xml
        `-- webapp
            |-- META-INF
            |   `-- MANIFEST.MF
            |-- WEB-INF
            |   `-- lib
            `-- index.jsp

My pom.xml looks like:

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
  xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.stackoverflow.q2418355</groupId>
  <artifactId>sample</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>
  <name>sample Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>javax</groupId>
      <artifactId>javaee-api</artifactId>
      <version>6.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.7</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>0.9.18</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.5.11</version>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.0.2</version>
        <configuration>
          <source>1.6</source>
          <target>1.6</target>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.1-beta-1</version>
        <configuration>
          <failOnMissingWebXml>false</failOnMissingWebXml>
        </configuration>
      </plugin>
    </plugins>
    <finalName>sample</finalName>
  </build>
</project>

The code for SimpleEJB.java is:

package com.stackoverflow.q2418355;

import javax.ejb.Stateless;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Stateless
public class SimpleEJB {
    private static Logger logger = LoggerFactory.getLogger(SimpleEJB.class);

    public String sayHello(String name) {
        logger.debug(">> sayHello()");
        logger.debug("<< sayHello()");
        return "Hello " + name + "!!!";
    }
}

The code for SimpleServlet.java is:

package com.stackoverflow.q2418355;

import java.io.IOException;
import java.io.PrintWriter;

import javax.ejb.EJB;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(urlPatterns = { "/SimpleServlet" })
public class SimpleServlet extends HttpServlet {
    @EJB
    SimpleEJB bean;

    private static Logger logger = LoggerFactory.getLogger(SimpleServlet.class);

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        logger.debug(">> doGet()");
        PrintWriter out = response.getWriter();
        out.println("<html><body>");
        out.println("<h2>Serving at: " + request.getContextPath() + "</h2>");
        out.println("<h2>Invoking EJB: " + bean.sayHello("Duke") + "</h2>");
        out.println("</body></html>");
        logger.debug("<< doGet()");
    }
}

The code for index.jsp is:

<html>
<body>
<h2>Hello World!</h2>
Invoke the Servlet by clicking <a href="SimpleServlet">here</a>.
</body>
</html>

And my logback.xml looks like:

<configuration>
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <layout class="ch.qos.logback.classic.PatternLayout">
      <Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</Pattern>
    </layout>
  </appender>

  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <File>/tmp/logs/testFile.log</File>
    <Append>true</Append>

    <layout class="ch.qos.logback.classic.PatternLayout">
      <Pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</Pattern>
    </layout>
  </appender>

  <logger name="com.stackoverflow.q2418355" level="TRACE"/>

  <root level="debug">
    <appender-ref ref="STDOUT" />
    <appender-ref ref="FILE" />
  </root>
</configuration>

My logback.xml gets propertly loaded and I get the following trace (taken from my log file) when invoking the servlet:

10913 [http-thread-pool-8080-(1)] DEBUG com.stackoverflow.q2418355.SimpleServlet - >> doGet()
10928 [http-thread-pool-8080-(1)] DEBUG com.stackoverflow.q2418355.SimpleEJB - >> sayHello()
10928 [http-thread-pool-8080-(1)] DEBUG com.stackoverflow.q2418355.SimpleEJB - << sayHello()
10932 [http-thread-pool-8080-(1)] DEBUG com.stackoverflow.q2418355.SimpleServlet - << doGet()

I did also try with the EJB packaged in its own JAR and deployed in WEB-INF/lib and get the same result, it just works. Can you spot any obvious difference? Maybe upload a simplified version of your app (will very likely be required for the bug report BTW).

I am running GlassFish v3 under Eclipse 3.5 (with the GlassFish v3 plugin).

这篇关于使用EJB3.1进行logback的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆