2017-04-25 51 views
0

我做錯了什麼,或者這是真正的預期行爲?讓我來解釋:沒有通過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(特別是logback實現)的命令行運行此程序時,我能夠得到該錯誤,但僅在控制檯輸出中。如果我以一種將所有控制檯輸出轉移到/ dev/null(例如)的方式運行這個例外,那麼這個異常永遠不會進入該文件,所以我不能告訴它發生了什麼。在出現錯誤之前,我可以儘可能多地登錄,所以在這方面它不是一個錯誤配置的問題。我甚至嘗試將jcl-over-slf4j和log4j-over-slf4j jar添加到classpath中,試圖找到一些無濟於事的東西。

也許我沒有使用正確的關鍵字,但我無法找到其他人報告相同的問題,所以我不能告訴這是我的配置中的問題還是Guice的「特性」。

所以基本上,這是一個配置問題或Guice中的「功能」/錯誤,我無法看到我的日誌文件中的綁定異常?

對於任何這裏仍然有興趣我logback.xml:

<?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並轉至標準錯誤)。

在修復方面,這取決於你想如何深刻調整設置:

  • 如果有某些對象的創建有可能失敗,並且希望應用程序繼續運行, 'd可能想要在try/catch區塊中捕獲CreationException。然後,您可以將日誌消息傳遞給SLF4J並正常恢復。

  • 如果這是一個程序,您不希望或期望控制檯的任何輸入或輸出,您可以通過System calls重置stdin,stdout和stderr,但這可能會被視爲令人困惑並且有些激烈。

  • this SO question一樣,您可以更改主線程的默認異常處理程序,以便失敗轉到SLF4J而不是stderr。但是,您可能仍然無法恢復:當您在線程中捕獲到異常時,無法恢復執行。

+0

謝謝,我能夠做一個快速測試,從你提到的SO問題中獲取一些代碼,並且允許我將錯誤提供給該文件。我在日誌文件中沒有看到文件的最大問題是程序實際上並沒有終止,因爲有些類創建了線程。因爲我沒有任何控制檯輸出,所以我無法診斷爲什麼某些內容不能按預期工作(直到我重定向標準錯誤)。 – wrestang

1

我已閱讀,吉斯用於其實現的Java記錄。我相信你看到的是Guice使用一個記錄器(即記錄到控制檯),然後SLF4J被配置爲你想要的日誌配置。你有沒有設定Guice使用SLF4J來實現其記錄器?

+0

隨着這種思想,我添加了七月到slf4j.jar到我的類路徑按[SLF4J文檔】(https://www.slf4j.org/legacy.html)也跟着的方案安裝步驟[更多slf4j文檔](https://www.slf4j.org/api/org/slf4j/bridge/SLF4JBridgeHandler.html)。不幸的是,這並沒有幫助。我將嘗試創建一個易於運行的問題示例。 – wrestang