获取 SLF4J 运行 而无需将任何内容复制到 WebLogic 库目录中

Get SLF4J running without coping anything into WebLogic lib-directory

我需要让 SLF4J 在 WebLogic 应用程序中运行。根据 Buttso [1] 和 Oracle [2],需要将文件复制到 domain/lib 目录:

然后在 logging.property 文件中定义以下处理程序:

 handlers = weblogic.logging.ServerLoggingHandler

并使用以下附加参数启动 WebLogic。

-Djava.util.logging.config.file=C:\tmp\logging.properties

我理解为什么 属性 文件必须全局定义。但我不明白,为什么必须将 JAR 复制到 WebLogic 的 domain/lib 目录中。 我试图将它们留在我的 WAR 文件中,但它不起作用。

有没有办法在应用程序的控制下保留日志库?这个限制从何而来?可以直接从应用程序中使用 Weblogic 的 JDK14 日志基础结构:

java.util.logging.Logger LOGGER = java.util.logging.Logger.getLogger("my.logger.Name");
LOGGER.info("JDK14 Anonymous info");

它按预期工作。处理程序 weblogic.logging.ServerLoggingHandler 能够成功拦截消息并将其转发到 WSL 日志文件中。为什么 SLF4J 桥不能做同样的事情?


[1] 将 SLF4J 与 WebLogic Server 日志记录结合使用 http://buttso.blogspot.com/2011/06/using-slf4j-with-weblogic-server.html

[2] 如何将 SLF4J 重定向到 WebLogic 日志系统? https://support.oracle.com/epmos/faces/DocumentDisplay?id=1507456.1(需要 Oracle 订阅)

镜头描述:

它与应用程序打包的 SLF4J 完美配合。重要的是 API slf4j-api 和实现 slf4j-jdk14 必须由同一个 classloader.

加载

详细说明:

默认情况下,Weblogic classloader 具有优先级。如果两个库(slf4j-apislf4j-jdk14)都位于 domain/lib 目录中,则不会出错。

如果 slf4j-api 位于应用程序 class 路径中但不在 Weblogic class 路径中,则可能发生两种情况:

  • SLF4J 发现一些与应用程序打包在一起的错误实现。例如,它可能是一个 logback 作为某些第三方库的强制依赖项。在这种情况下,消息将被转发到错误的实现中,并且它们不会到达 WebLogic 日志记录基础结构。

  • SLF4J 在 WebLogic class 路径中找到一些实现。在这种情况下,应用程序很可能会因为 ClassCastException.

    而无法部署

如我所说,可以在应用程序中包含所有 SLF4J 日志记录库。例如,如果 WebLogic 服务器是共享实例并且不受您的控制,则需要它。需要做两件事:

  • 确保只有一个 SLF4J 实现与应用程序打包在一起。在我们的例子中是 slf4j-jdk14。做 maven clean 以确保,之前尝试的所有遗留物都已从 WAR 文件中删除!

  • 强制使用应用程序 classloader 来加载 SLF4J 库。 WEB-INF/weblogic.xml 是这样完成的:

    <wls:weblogic-web-app xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-web-app" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd http://xmlns.oracle.com/weblogic/weblogic-web-app http://xmlns.oracle.com/weblogic/weblogic-web-app/1.9/weblogic-web-app.xsd">
        <wls:weblogic-version>14.1.1.0</wls:weblogic-version>
        <wls:context-root>test-oauth</wls:context-root>
        <wls:container-descriptor>
            <wls:prefer-application-packages>
                <wls:package-name>org.slf4j.*</wls:package-name>
            </wls:prefer-application-packages>
        </wls:container-descriptor>
    </wls:weblogic-web-app>
    

这是一个有用的示例,如何找出哪个 classloader 负责给定的 class 或实例。