我做错了什么,或者这是真正预期的行为?让我解释一下:
当尝试使用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>
答案 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。但是,您可能仍然无法恢复:当您在线程中捕获异常时,其他任何地方都无法恢复执行。