没有通过 SLF4J 将 Guice 注入问题归档
Not getting Guice injection issues via SLF4J to file
我是在做错什么,还是这真的是预期的行为?让我解释一下:
当尝试使用 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 添加到类路径中以尝试获取一些无济于事的东西。
也许我没有使用正确的关键字,但我找不到其他人报告相同的问题,所以我无法判断这是我的配置问题还是 "feature"吉斯
基本上,这是配置问题还是 Guice 中的 "feature"/错误,我无法在日志文件中看到绑定异常?
对于任何仍然感兴趣的人,这里是我的 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>
我读到 Guice 使用 Java 记录器来实现它。我相信您看到的是 Guice 使用一个记录器(记录到控制台),然后使用您想要的日志记录配置配置 SLF4J。您是否将 Guice 设置为使用 SLF4J 实现其记录器?
您看到的不是日志警告,它是主线程上的异常,并且 Java 在终止您的程序之前尽职地将其记录到标准错误。我不相信 SLF4J 会重定向 stderr,或者更改默认的异常处理程序;对于包括 throw new RuntimeException()
.
在内的任何异常,您都会得到相同的行为(跳过 SLF4J 并转到标准错误)
就修复而言,这取决于您要调整设置的深度:
如果某些对象创建可能会失败,并且您希望应用继续 运行,您可能希望在 CreationException
中捕获 try
/catch
块。然后您可以将日志消息传递给 SLF4J 并优雅地恢复。
如果这是一个您不希望或不期望任何输入或输出控制台的程序,您可以通过 System
calls 重置 stdin、stdout 和 stderr,但这可能被视为令人困惑且有些激烈。
与 this SO question 一样,您可以更改主线程的默认异常处理程序,以便将失败转到 SLF4J 而不是 stderr。但是,您可能仍然无法恢复:当您在线程中捕获异常时,没有其他地方可以恢复执行。
我是在做错什么,还是这真的是预期的行为?让我解释一下:
当尝试使用 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 添加到类路径中以尝试获取一些无济于事的东西。
也许我没有使用正确的关键字,但我找不到其他人报告相同的问题,所以我无法判断这是我的配置问题还是 "feature"吉斯
基本上,这是配置问题还是 Guice 中的 "feature"/错误,我无法在日志文件中看到绑定异常?
对于任何仍然感兴趣的人,这里是我的 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>
我读到 Guice 使用 Java 记录器来实现它。我相信您看到的是 Guice 使用一个记录器(记录到控制台),然后使用您想要的日志记录配置配置 SLF4J。您是否将 Guice 设置为使用 SLF4J 实现其记录器?
您看到的不是日志警告,它是主线程上的异常,并且 Java 在终止您的程序之前尽职地将其记录到标准错误。我不相信 SLF4J 会重定向 stderr,或者更改默认的异常处理程序;对于包括 throw new RuntimeException()
.
就修复而言,这取决于您要调整设置的深度:
如果某些对象创建可能会失败,并且您希望应用继续 运行,您可能希望在
CreationException
中捕获try
/catch
块。然后您可以将日志消息传递给 SLF4J 并优雅地恢复。如果这是一个您不希望或不期望任何输入或输出控制台的程序,您可以通过
System
calls 重置 stdin、stdout 和 stderr,但这可能被视为令人困惑且有些激烈。与 this SO question 一样,您可以更改主线程的默认异常处理程序,以便将失败转到 SLF4J 而不是 stderr。但是,您可能仍然无法恢复:当您在线程中捕获异常时,没有其他地方可以恢复执行。