2017-04-25 12 views
0

私は何か間違っているのですか、これは本当に予想される動作ですか?私に説明してみましょう:Guice注入問題がSLF4J経由でファイルに出力されない

私のクラスパス(または任意の他の結合の問題)に何か問題がある場合は、GuiceのDIでJavaプログラムを実行しようとすると、私は次のようになります例外を得ることを期待:

Exception in thread "main" com.google.inject.CreationException: Guice creation errors:

1) Error injecting constructor, java.lang.NoClassDefFoundError: Could not initialize class <any class here>

これは実際に私にクラスパスの問題があることを知らせてくれます。私はGuiceについて愛していることの一つです(何が間違っているのか正確に伝えています)。

SLF4J(特にログバック実装)を使用してこのプログラムをコマンドライン経由で実行すると、コンソール出力でのみエラーが発生します。すべてのコンソール出力を/ dev/null(たとえば)に変換する方法でこれを実行すると、例外がファイルに出力されることはありませんので、私はそれが起こっているとは言えません。私はエラーの前に私が望むようにログすることができるので、それはその点で悪い構成の問題ではありません。私はjcl-over-slf4jとlog4j-over-slf4j jarsをクラスパスに追加して、無駄なものを拾い上げようと試みました。

私は適切なキーワードを使用していないかもしれませんが、私は同じ問題を報告している誰かを見つけることができないので、これが自分の設定やGuiceの "機能"に問題があるかどうかはわかりません。

これは基本的な問題ですか、これは構成上の問題かGuiceの "機能" /バグで、私はログファイルにバインディング例外を見ることができませんか?私はGuiceのは、その実装のためのJavaロガーを使用していることを読んだ

<?xml version="1.0" encoding="UTF-8"?> 
<configuration scan="true" scanPeriod="30 seconds"> 
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> 
     <file>debug.log</file> 
     <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> 
      <Pattern>%d{yyyy-MM-dd_HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</Pattern> 
     </encoder> 

     <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> 
      <FileNamePattern>debug.%i.log.zip</FileNamePattern> 
      <MinIndex>1</MinIndex> 
      <MaxIndex>10</MaxIndex> 
     </rollingPolicy> 

     <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> 
      <MaxFileSize>2MB</MaxFileSize> 
     </triggeringPolicy> 
    </appender> 

    <appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender"> 
     <appender-ref ref="FILE" /> 
    </appender> 

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> 
     <encoder> 
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 
      </pattern> 
     </encoder> 
    </appender> 

    <appender name="ASYNC_CONSOLE" class="ch.qos.logback.classic.AsyncAppender"> 
     <appender-ref ref="STDOUT" /> 
    </appender> 

    <root level="debug"> 
     <appender-ref ref="ASYNC_FILE" /> 
     <appender-ref ref="ASYNC_CONSOLE" /> 
    </root> 
</configuration> 

答えて

1

あなたが見ているのはログの警告ではなく、メインスレッド上の例外です。Javaは、プログラムを終了する前に標準エラーに忠実にログを記録しています。私はSLF4Jがstderrをリダイレクトしたり、デフォルトの例外ハンドラを変更したりするとは思わない。 throw new RuntimeException()を含む例外については、同じ動作(SLF4Jをスキップして標準エラーになります)が発生します。あなたのセットアップを調整する方法を深く依存する修正の観点で

、:

  • あなたは、そこに失敗する可能性がある特定のオブジェクトの作成があり、あなたはアプリが実行を継続したい場合はおそらくtry/catchブロックのCreationExceptionをキャッチしたいと考えています。その後、ロギング・メッセージをSLF4Jに渡して正常に回復できます。

  • コンソールが入出力を必要としない、または期待しないプログラムの場合は、stdin、stdout、およびstderrをSystem callsでリセットできますが、これは混乱し、やや劇的なものです。

  • this SO questionのように、メインスレッドのデフォルトの例外ハンドラを変更することができます。そのため、障害はstderrの代わりにSLF4Jに送られます。しかし、おそらくまだ回復することはできません。スレッドで例外をキャッチするときまでに、実行を再開する場所はありません。その思想と

+0

ありがとう、私はあなたが言及したSOの質問からいくつかのコードを取得する迅速なテストを行うことができた、それは私がファイルにエラーを取得することができます。ログファイルに表示されないファイルに関する私の最大の問題は、スレッドを作成するクラスによってプログラムが実際に終了しないことです。私はコンソール出力がないので、何かが期待どおりに動作しない理由を診断する方法がありません(標準エラーにリダイレクトするまで)。 – wrestang

1

:ここにまだ興味のために

は私logback.xmlです。私はあなたが見ているものは、Guiceが(コンソールにロギングしている)1つのロガーを使用していることを信じていますし、SLF4Jはあなたの希望するロギング設定で構成されています。 Guiceは、ロガーの実装にSLF4Jを使用するように設定しましたか?

+0

、私は[SLF4Jのドキュメント](https://www.slf4j.org/legacy.html)あたりとしての私のクラスパスに7月ツーslf4j.jarを追加しても、プログラムのインストールを追いました[more slf4j documentation]の手順(https://www.slf4j.org/api/org/slf4j/bridge/SLF4JBridgeHandler.html)。残念ながら、これは役に立たなかった。私はこの問題の簡単に実行可能な例を作成しようとしています。 – wrestang

関連する問題