没有通过SLF4J将Guice注入问题发送到文件

时间:2017-04-25 19:11:34

标签: java guice slf4j

我做错了什么,或者这是真正预期的行为?让我解释一下:

当尝试使用Guice DI运行Java程序时,如果我的类路径(或任何其他绑定问题)出现问题,我希望得到一个看起来像这样的异常:

  

线程“main”中的异常com.google.inject.CreationException:Guice创建错误:

     

1)注入构造函数时出错,java.lang.NoClassDefFoundError:无法初始化类<any class here>

这实际上让我知道我有一个类路径问题,这是我喜欢Guice的事情之一(告诉你到底出了什么问题)。

当我使用SLF4J(特别是logback实现)通过命令行运行此程序时,我能够获得该错误,但仅限于控制台输出。如果我以将所有控制台输出转移到/ dev / null(例如)的方式运行它,则异常永远不会进入文件,因此我无法告诉它正在发生。我可以在错误之前记录我想要的内容,因此在这方面不是一个错误配置的问题。我甚至尝试将jcl-over-slf4j和log4j-over-slf4j jars添加到类路径中以尝试拾取某些东西但无济于事。

也许我没有使用正确的关键字,但我无法找到报告相同问题的其他人,所以我无法判断这是我配置中的问题还是Guice的“功能”。 / p>

所以基本上,这是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>

2 个答案:

答案 0 :(得分:1)

我已经读过Guice使用Java记录器来实现它。我相信你看到的是Guice使用一个记录器(即登录到控制台),然后SLF4J配置了你想要的记录配置。您是否已将Guice设置为使用SLF4J进行记录器实现?

答案 1 :(得分:1)

您所看到的不是日志警告,它是主线程上的异常,Java在终止您的程序之前尽职尽责地将其记录到标准错误。我不相信SLF4J会重定向stderr,或者更改默认的异常处理程序;对于包括throw new RuntimeException()在内的任何异常,您都会获得相同的行为(跳过SLF4J并转到标准错误)。

就修复而言,这取决于您想要调整设置的深度:

  • 如果某些对象创建可能会失败,并且您希望该应用继续投放,那么您可能希望在CreationException / {中抓住try {1}}阻止。然后,您可以将日志消息传递给SLF4J并正常恢复。

  • 如果这是一个您不希望或期望控制台输入或输出的程序,您可以通过System calls重置stdin,stdout和stderr,但是可以看到令人困惑,有点激烈。

  • this SO question一样,您可以更改主线程的默认异常处理程序,以便将失败转到SLF4J而不是stderr。但是,您可能仍然无法恢复:当您在线程中捕获异常时,其他任何地方都无法恢复执行。