java - 使用 EJB3.1 登录

标签 java glassfish ejb-3.0 logback slf4j

我正在使用 logback/slf4j 来处理我的应用程序中的日志记录。在我开始使用 EJB 之前,一切都运行良好。在我将无状态 EJB 添加到我的应用程序后,记录器开始忽略我的 logback.xml 并停止使用我的附加程序。我切换到编程记录器配置以查看问题所在,现在当我尝试在 EJB 中使用我的记录器时出现以下错误:

org.slf4j.impl.JDK14LoggerFactory 无法转换为 ch.qos.logback.classic.LoggerContext

源于行:

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

是否需要任何特殊配置才能让 logback 与 EJB 一起工作?如果重要的话,我会在 glassfish v3 上部署。

最佳答案

这看起来非常接近 this thread 中描述的问题我怀疑有类似的类加载问题。由于 logback 加载的方式 logback.xml (更准确地说是它检索 ClassLoader 的方式),它可能无法获取其配置文件并退回到默认的 BasicConfiguration。 .

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

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

更新:如果您使用 war 包装,请尝试将 GlassFish 配置为在委托(delegate)之前首先使用子类加载器。在sun-web.xml :

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

<罢工>


更新:我在我这边做了一点测试......我无法重现你的问题。我已经为具有以下结构的 Java EE 6 webapp 创建了一个项目:

$ 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>

SimpleEJB.java 的代码是:

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 + "!!!";
    }
}

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" })
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()");
    }
}

index.jsp 的代码是:

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

还有我的logback.xml看起来像:

<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>

我的 logback.xml正确加载并且在调用 servlet 时得到以下跟踪(取 self 的日志文件):

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 中并得到相同的结果,它只是有效。你能发现任何明显的区别吗?也许上传您的应用程序的简化版本(顺便说一句,错误报告很可能需要)。

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

关于java - 使用 EJB3.1 登录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2418069/

相关文章:

java - 在 Cucumber 步骤运行时将关键字解析为其值

java - Glassfish 和 Verisign 试用测试证书

java - 我的网络应用程序 (JSF 2.0) 的简单登录和注销功能

java - EJB 3.0。为客户端提供接口(interface)

java - Spring 安全: redirect logged user depending on some conditions

使用 java 编码时 Eclipse 崩溃。退出代码=-1073740771

java - Apache 弗林克 : Extract TypeInformation of Tuple

java - 在 glassfish 服务器上运行应用程序时 Eclipse 未打开浏览器

java - 使用 Glassfish 3.1.2 和 JAAS 登录 JSF 2.0

java - 如何通过远程接口(interface)使用@EJB”