2013-08-08 2 views
6

Мой проект упакован как файл EAR, содержащий API SLF4J (1.7.5), а также библиотеки журналов в качестве его реализации (logback-core 1.0.13 и logback-classic 1.0.13).SLF4J - Привязки перезаписываются другими приложениями на том же сервере приложений

Когда я использовал (используется) для развертывания моего проекта SLF4J's LoggerFactory находит логин как возможную привязку и используется правильный регистратор (т. Е. Журнал).

Теперь у меня есть коннектор ресурсов (activemq-rar-5.8.0.rar), который развертывается перед моим собственным EAR-файлом (поскольку файлы EAR требуют RAR). К сожалению, этот RAR содержит собственную реализацию SLF4J (slf4j-api-1.6.6.jarslf4j-log4j12-1.6.6.jarlog4j-1.2.17.jar). Файлы RAR используют реализацию log4j.

Когда я развертываю свой EAR-файл, LoggerFactory внутри кода моего приложения внезапно использует реализацию log4j (org.slf4j.impl.Log4jLoggerAdapter) - хотя я ожидал, что путь к классам будет отделен от RAR.

Это не похоже на то, что я делаю неправильно (RAR должен использовать log4j, мой EAR должен использовать logback)?


Update 1: It doesn't look as if I am alone, но, к сожалению, ответ отсутствует ..


Update 2:

Согласно this таблице, GlassFish загружает модуль разъема перед EAR/WAR libs (которые являются последними загружаемыми libs).


Update 3:

мне удалось зафиксировать "привязку": Если бы я поставил slf4j-api-1.7.5.jar и реализацию Logback (logback-core-1.0.13.jar и logback-classic-1.0.13.jar) внутри domains/<myDomain>/lib папки в GlassFish, будет использоваться Logback как реализация журнала (см. «Обновление 2» - «Common Classloader» появляется перед «Connector Classloader»).

К сожалению, мои конфигурационные файлы больше не найдены, поскольку они находятся внутри WAR/EAR, которые позже будут загружены другим загрузчиком классов («Archive Classloader»).

Так что это не решение для меня, так как я хотел бы сохранить файлы конфигурации журнала в EAR/WAR (так как каждое приложение использует другую конфигурацию).


С наилучшими пожеланиями

stupidSheep

+0

Почему пакет log4j в зависимости? Не может ли контейнер следить за конфигурацией ведения журнала и предоставлять им? – roby

+0

Я не собираю log4j как зависимость самостоятельно. Он находится в RAR (адаптере ресурсов), который выполняется Apache ActiveMQ (http://activemq.apache.org/maven/5.8.0/activemq-rar/dependencies.html). Эти JAR-файлы находятся внутри RAR вместе с некоторыми файлами конфигурации журнала. – stupidSheep

ответ

1

я наконец понял, приемлемое решение.

GlassFish загружает модуль разъема перед EAR/WAR, см. «Обновление 2». Предоставляя реализацию SLF4J ДО ТОГО, когда модуль соединителя загружается, моя реализованная реализация SLF4J используется.

Для этого я скопировал следующие JARS в каталог domains/<myDomain>/lib (см. «Обновление 3»).

  • logback-core-1.0.13.jar
  • logback-classic-1.0.13.jar
  • slf4j-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()); 
    } 
} 

Это будет настроить logback. Обратите внимание, что для этого я использовал специальный код журнала, поэтому, если вы изменили реализацию SLF4J, вы должны также изменить LoggerProducer.

Я думаю, что logback не находит свой файл конфигурации, так как «Common Classloader» не имеет EAR/WAR на пути к классу. Но позже, когда приложение загружено, «Archive Classloader» имеет logback.xml в своем пути к классам (как это предусмотрено файлом EAR/WAR), так что можно настроить logback, как только все будет на месте.

С уважением, stupidSheep

+0

Оказывается, это не сработает. Последнее загружаемое приложение переопределит конфигурацию регистратора. – stupidSheep

+0

Совершенно обработанная работа. – Sam

Смежные вопросы