让 SLF4J 运行而无需将任何内容处理到 WebLogic 库目录中
Posted
技术标签:
【中文标题】让 SLF4J 运行而无需将任何内容处理到 WebLogic 库目录中【英文标题】:Get SLF4J running without coping anything into WebLogic lib-directory 【发布时间】:2022-01-23 17:32:28 【问题描述】:我需要让 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 订阅)
【问题讨论】:
【参考方案1】:镜头说明:
它与应用程序打包的 SLF4J 完美配合。重要的是 API slf4j-api
和实现 slf4j-jdk14
必须由同一个类加载器加载。
详细说明:
默认情况下,Weblogic 类加载器具有优先级。如果两个库(slf4j-api
和 slf4j-jdk14
)都位于 domain/lib
目录中,则不会出错。
如果 slf4j-api
位于应用程序类路径中但不在 Weblogic 类路径中,则可能发生两种情况:
SLF4J 发现一些与应用程序打包在一起的错误实现。例如,它可能是作为某些第三方库的强制依赖项的 logback。在这种情况下,消息将被转发到错误的实现中,并且不会到达 WebLogic 日志基础架构。
SLF4J 在 WebLogic 类路径中找到了一些实现。在这种情况下,应用程序很可能会因为ClassCastException
而无法部署。
正如我所说,可以在应用程序中包含所有 SLF4J 日志库。例如,如果 WebLogic 服务器是共享实例并且不受您的控制,则需要它。需要做两件事:
确保只有一个 SLF4J 实现与应用程序打包在一起。在我们的例子中是slf4j-jdk14
。确保maven clean
确保之前尝试的所有剩余都从 WAR 文件中删除!
强制使用应用程序类加载器来加载 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>
这是一个有用的示例,如何找出哪个类加载器负责给定的类或实例。
Which classloader loaded a class of the provided instance
【讨论】:
以上是关于让 SLF4J 运行而无需将任何内容处理到 WebLogic 库目录中的主要内容,如果未能解决你的问题,请参考以下文章
为啥使用 SLF4J 而不是 Log4J 来做 Java 日志
根据输入到单元格中的数字为单元格分配颜色和值,而无需点击运行按钮