2013-08-08 4 views
6

私のプロジェクトはSLF4J API(1.7.5)とその実装としてのログバックライブラリ(logback-core 1.0.13logback-classic 1.0.13)を含むEARファイルとしてパッケージ化されています。SLF4J - 同じアプリケーションサーバー上の他のアプリケーションによってバインディングが上書きされる

私のプロジェクトを配備するとき、SLF4JのLoggerFactoryは可能なバインディングとしてログバックを見つけ、正しいロガー(ログバック)が使用されます。

私は自分のEARファイル(EARファイルにはRARが必要)の前に配備されているリソースコネクタ(activemq-rar-5.8.0.rar)を持っています。残念ながら、このRARには独自のSLF4J実装(slf4j-api-1.6.6.jarslf4j-log4j12-1.6.6.jarlog4j-1.2.17.jar)が含まれています。 RARファイルはlog4j実装を使用します。

EARファイルを配備すると、クラスパスがRARから分離されることが予想されていましたが、アプリケーションのコード内にLoggerFactoryが突然log4j実装(org.slf4j.impl.Log4jLoggerAdapter)を使用します。

これはそうではないようです - 私は間違っています(RARはlog4jを使用すべきです、私のEARはログバックを使用すべきです)?


アップデート1: It doesn't look as if I am aloneが、残念ながら答えは見つからない。..


アップデート2:

this表によると、GlassFishのは、前にコネクタモジュールをロードしますEAR/WAR libs(ロードされる最後のlibです)。


アップデート3:私はGlassFishの中domains/<myDomain>/libフォルダ内slf4j-api-1.7.5.jarとlogbackの実装(logback-core-1.0.13.jarlogback-classic-1.0.13.jar)を入れた場合は、logbackが使用されます:

私は "結合" を修正するために管理(更新2 - 「共通クラスローダー」は「コネクター・クラスローダー」の前にあります)を参照してください。

残念ながら、私の設定ファイルはWAR/EARの中にあるので、もう見つけられません。後で別のクラスローダー( "Archive Classloader")によってロードされます。

EAR/WARの中にログバック設定ファイルを保存したいので(これはすべてのアプリケーションが別の設定を使用しているので)、これは本当に私にとっては解決策ではありません。


種類はstupidSheep

+0

なぜlog4jを依存関係にパッケージ化するのですか?コンテナはロギング設定を見てインプラントを提供できませんか? – roby

+0

私は自分自身でlog4jを依存関係としてパックしません。これは、Apache ActiveMQ(http://activemq.apache.org/maven/5.8.0/activemq-rar/dependencies.html)によって証明されたRAR(リソースアダプタ)にあります。これらのJARファイルは、いくつかのログ構成ファイルとともにRAR内にあります。 – stupidSheep

答えて

1

に関しては、私は最終的に受け入れ可能な解決策を考え出しました。

EAR/WARの前にGlassFishがコネクタモジュールを読み込みます(「Update 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内にあります)。

解決策は、ログバックを手動で設定することです。私は次の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()); 
    } 
} 

これはログバックを構成します。私はそれを行うためにログバック固有のコードを使用していますので、SLF4Jの実装を変更する場合は、LoggerProducerも変更する必要があります。

「Common Classloader」のクラスパスにEAR/WARがないので、logbackは設定ファイルを見つけられません。しかし、アプリケーションがロードされると、アーカイブクラスローダーはそのクラスパスに(EAR/WARファイルで提供されているように)logback.xmlを持つので、すべての設定が完了したらログバックを設定することができます。

よろしくお願いします。stupidSheep

+0

これは動作しません。最後にロードされるアプリケーションは、ロガーの設定を上書きします。 – stupidSheep

+0

完璧に細工された仕事です。 – Sam

関連する問題