stu*_*eep 6 java activemq-classic glassfish classpath slf4j
我的一个项目打包为一个EAR文件,其中包含SLF4J API(1.7.5)以及作为其实现(logback-core 1.0.13和logback-classic 1.0.13)的logback库.
当我(以前)部署我的项目时,SLF4J的LoggerFactory发现logback尽可能绑定并使用正确的记录器(即logback).
现在我有一个资源连接器(activemq-rar-5.8.0.rar),它在我自己的EAR文件之前部署(因为EAR文件需要RAR).不幸的是,这个RAR包含自己的SLF4J实现(slf4j-api-1.6.6.jar slf4j-log4j12-1.6.6.jar log4j-1.2.17.jar).RAR文件使用log4j实现.
当我部署我的EAR文件时,我的应用程序代码中的LoggerFactory突然使用log4j实现(org.slf4j.impl.Log4jLoggerAdapter) - 即使我希望类路径与RAR分离.
这似乎不是这样 - 所以我做错了什么(RAR应该使用log4j,我的EAR应该使用logback)?
更新1: 看起来我并不孤单,但不幸的是,答案遗失了......
更新2:
根据此表,GlassFish在EAR/WAR库之前加载连接器模块(这是最后要加载的库).
更新3:
我设法修复了"绑定":如果我将slf4j-api-1.7.5.jar和logback实现(logback-core-1.0.13.jar和logback-classic-1.0.13.jar)放在domains/<myDomain>/libGlassFish 的文件夹中,则logback将用作日志记录实现(请参阅Update 2 - "Common Classloader"在"Connector Classloader"之前).
不幸的是我的配置文件不再存在,因为它们在WAR/EAR中 - 稍后将由不同的类加载器("Archive Classloader")加载.
所以这对我来说并不是真正的解决方案,因为我希望将回溯配置文件保留在EAR/WAR中(因为每个应用程序都使用不同的配置).
亲切的问候
stupidSheep
我终于找到了一个可以接受的解决方案。
GlassFish 在 EAR/WAR 之前加载连接器模块,请参阅“更新 2”。通过在加载连接器模块之前提供 SLF4J 实现,可以使用我提供的 SLF4J 实现。
为此,我将以下 JAR 复制到该目录中domains/<myDomain>/lib(请参阅“更新 3”)。
logback-core-1.0.13.jarlogback-classic-1.0.13.jarslf4j-api-1.7.5.jar不幸的是,logback 不再找到它自己的配置文件 ( logback.xml),它必须位于类路径上(确实如此,因为我将它打包在 JAR 中)。
解决办法是手动配置logback。我使用以下 CDI 生成器完成了此操作:
package com.example;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.joran.spi.JoranException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.PostConstruct;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.InjectionPoint;
@ApplicationScoped
public class LoggerProducer {
@PostConstruct
public void initialize() {
// The following is logback specific. Unfortunately logback doesn't find its XML configuration
// as the logback implementation gets loaded by a different ClassLoader than this code.
// See http://docs.oracle.com/cd/E19226-01/820-7695/6niugesfp/index.html#indexterm-28
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
JoranConfigurator joranConfigurator = new JoranConfigurator();
joranConfigurator.setContext(lc);
lc.reset();
try {
// The logback configuration is now being loaded from the classpath (by the "Archive Classloader")
joranConfigurator.doConfigure(this.getClass().getClassLoader().getResource("logback.xml"));
} catch (JoranException e) {
e.printStackTrace();
}
}
@Produces
@ApplicationLogger
Logger createLogger(InjectionPoint injectionPoint) {
return LoggerFactory.getLogger(injectionPoint.getMember().getDeclaringClass());
}
}
Run Code Online (Sandbox Code Playgroud)
这将配置 logback。LoggerProducer请注意,我使用了 logback 特定代码来执行此操作,因此如果您更改 SLF4J 实现,您也必须更改。
我认为 logback 找不到它的配置文件,因为“通用类加载器”的类路径上没有 EAR/WAR。但稍后,当加载应用程序时,“存档类加载器”的logback.xml类路径上会包含 (因为它是由 EAR/WAR 文件提供的),因此一旦一切就绪,就可以配置 logback。
问候愚蠢的羊
| 归档时间: |
|
| 查看次数: |
1677 次 |
| 最近记录: |