Java 未通过SLF4J将Guice注入问题获取到文件
我是做错了什么,还是这真的是预期的行为?让我解释一下: 当尝试使用Guice DI运行Java程序时,如果我的类路径出现问题(或任何其他绑定问题),我希望得到如下异常: 线程“main”com.google.inject.CreationException中出现异常:Guice创建错误: 1) 注入构造函数java.lang.NoClassDefFoundError时出错:无法初始化类Java 未通过SLF4J将Guice注入问题获取到文件,java,guice,slf4j,Java,Guice,Slf4j,我是做错了什么,还是这真的是预期的行为?让我解释一下: 当尝试使用Guice DI运行Java程序时,如果我的类路径出现问题(或任何其他绑定问题),我希望得到如下异常: 线程“main”com.google.inject.CreationException中出现异常:Guice创建错误: 1) 注入构造函数java.lang.NoClassDefFoundError时出错:无法初始化类 这实际上让我知道我有一个类路径问题,这也是我喜欢Guice的原因之一(告诉你到底出了什么问题) 当我使用SLF
这实际上让我知道我有一个类路径问题,这也是我喜欢Guice的原因之一(告诉你到底出了什么问题)
当我使用SLF4J(特别是logback实现)通过命令行运行这个程序时,我能够得到那个错误,但只能在控制台输出中得到。如果我以一种将所有控制台输出转移到/dev/null(例如)的方式运行它,那么异常永远不会进入文件,因此我无法判断它正在发生。在发生错误之前,我可以记录任意数量的日志,因此在这方面,这不是一个错误配置的问题。我甚至尝试将jcl-over-slf4j和log4j-over-slf4j jar添加到类路径中,试图获取一些无效的东西
也许我没有使用正确的关键字,但我找不到其他人报告相同的问题,因此我无法判断这是我的配置中的问题还是Guice的“功能”
那么基本上,这是一个配置问题还是Guice中的一个“feature”/bug,我无法在日志文件中看到绑定异常
对于任何仍然感兴趣的人,这里是我的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>
调试日志
%d{yyyy-MM-dd_HH:MM:ss.SSS}[%thread]-5级别%logger{36}-%msg%n
调试。%i.log.zip
1.
10
2MB
%d{HH:mm:ss.SSS}[%thread]-5级别%logger{36}-%msg%n
我读到Guice使用Java logger来实现它。我相信您看到的是Guice使用一个记录器(即登录到控制台),然后SLF4J被配置为您所需的日志配置。您是否已将Guice设置为使用SLF4J实现其记录器?您看到的不是日志警告,而是主线程上的异常,Java在终止程序之前会尽职尽责地将其记录为标准错误。我不相信SLF4J会重定向stderr,或者更改默认的异常处理程序;对于任何异常,包括抛出新的RuntimeException()
,您都会得到相同的行为(跳过SLF4J并转到标准错误)
就修复而言,这取决于您希望调整设置的深度:
- 如果某些对象创建可能会失败,并且您希望应用程序继续运行,那么您可能希望在
/try
块中捕获catch
。然后,您可以将日志消息传递给SLF4J并正常恢复CreationException
- 如果这是一个您不希望或不希望控制台进行任何输入或输出的程序,您可以通过重置stdin、stdout和stderr,但这可能会被视为混乱和有点激烈
- 与中一样,您可以更改主线程的默认异常处理程序,以便将故障转移到SLF4J而不是stderr。但是,您可能仍然无法恢复:当您捕获线程中的异常时,没有其他地方可以恢复执行