2013-08-08 12 views
6

Mój projekt jest pakowany jako plik EAR zawierający interfejs API SLF4J (1.7.5) oraz biblioteki logback jako jego implementację (logback-core 1.0.13 i logback-classic 1.0.13).SLF4J - Wiązania są zastępowane przez inne aplikacje na tym samym serwerze aplikacji.

Kiedy (użyłem) do wdrożenia mojego projektu, LoggerFactory SLF4J znajduje logback jako możliwe powiązanie i używany jest prawidłowy rejestrator (to jest logback).

Mam teraz łącznik zasobów (activemq-rar-5.8.0.rar), który jest wdrażany przed moim własnym plikiem EAR (ponieważ pliki EAR wymagają wersji RAR). Niestety ten RAR zawiera własną implementację SLF4J (slf4j-api-1.6.6.jarslf4j-log4j12-1.6.6.jarlog4j-1.2.17.jar). Pliki RAR używają implementacji log4j.

Kiedy wdrażam plik EAR, LoggerFactory wewnątrz kodu mojej aplikacji nagle korzysta z implementacji log4j (org.slf4j.impl.Log4jLoggerAdapter) - mimo że spodziewałem się oddzielenia ścieżki klas od RAR.

Nie wydaje się, żeby tak było - więc co robię źle (RAR powinien używać log4j, moje EAR powinno używać logback)?


Aktualizacja 1: It doesn't look as if I am alone, ale niestety odpowiedź brakuje ..


Aktualizacja 2:

Według this stole, GlassFish ładuje moduł złącza przed biblioteki EAR/WAR (które są ostatnimi bibliotekami do załadowania).


Update 3:

udało mi się naprawić "wiązanie": Jeśli mogę umieścić slf4j-api-1.7.5.jar i realizację logback (logback-core-1.0.13.jar i logback-classic-1.0.13.jar) wewnątrz folderu w GlassFish domains/<myDomain>/lib, logback zostaną wykorzystane jako implementacja logowania (patrz Aktualizacja 2 - "Common Classloader" pojawia się przed "Connector Classloader").

Niestety, moje pliki konfiguracyjne nie są już znalezione, ponieważ znajdują się wewnątrz WAR/EAR - które zostaną załadowane później przez inny program ładujący klasy ("Archive Classloader").

To nie jest tak naprawdę rozwiązanie dla mnie, ponieważ chciałbym zachować pliki konfiguracyjne logback w EAR/WAR (ponieważ każda aplikacja używa innej konfiguracji).


Rodzaj odniesieniu

stupidSheep

+0

Dlaczego pakiet log4j w zależności? Czy kontener nie może zająć się konfiguracją rejestrowania i dostarczyć imp? – roby

+0

Nie pakuję log4j jako zależności przez siebie. Jest w RAR (adapterze zasobów) udostępnianym przez Apache ActiveMQ (http://activemq.apache.org/maven/5.8.0/activemq-rar/dependencies.html). Te pliki JAR znajdują się wewnątrz RAR wraz z niektórymi plikami konfiguracyjnymi dziennika. – stupidSheep

Odpowiedz

1

końcu wzorzyste się do przyjęcia rozwiązania.

GlassFish ładuje moduł złącza przed EAR/WAR, patrz "Aktualizacja 2". Zapewniając implementację SLF4J PRZED załadowaniem modułu złącza, używana jest moja implementacja SLF4J.

W tym celu skopiowałem następujące pliki JARS do katalogu domains/<myDomain>/lib (patrz "Aktualizacja 3").

  • logback-core-1.0.13.jar
  • logback-classic-1.0.13.jar
  • slf4j-api-1.7.5.jar

Niestety logback nie znaleźliśmy własny plik konfiguracyjny (logback.xml) anymore, które muszą znajdować się na ścieżce klasy (co to jest, jak spakowałem to wewnątrz JAR).

Rozwiązaniem jest ręczne skonfigurowanie logback. Zrobiłem to za pomocą następującego producenta 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()); 
    } 
} 

Spowoduje to skonfigurowanie logback. Zwróć uwagę, że użyłem do tego specjalnego kodu zwrotnego, więc jeśli zmienisz implementację SLF4J, musisz również zmienić LoggerProducer.

Myślę, że logback nie znajduje pliku konfiguracyjnego, ponieważ "Common Classloader" nie ma EAR/WAR na swojej ścieżce klasy. Później, po załadowaniu aplikacji, "Archive Classloader" ma logback.xml na swojej ścieżce klasowej (tak jak jest dostarczony przez plik EAR/WAR), więc możliwe jest skonfigurowanie logback, gdy wszystko będzie już gotowe.

Pozdrowienia stupidSheep

+0

Okazuje się, że to nie działa. Ostatnia aplikacja, która ma zostać załadowana, zastąpi konfigurację rejestratora. – stupidSheep

+0

Idealnie wykonana robota. – Sam

Powiązane problemy