Java 未通过SLF4J将Guice注入问题获取到文件

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 DI运行Java程序时,如果我的类路径出现问题(或任何其他绑定问题),我希望得到如下异常:

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

1) 注入构造函数java.lang.NoClassDefFoundError时出错:无法初始化类

这实际上让我知道我有一个类路径问题,这也是我喜欢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
    块中捕获
    CreationException
    。然后,您可以将日志消息传递给SLF4J并正常恢复

  • 如果这是一个您不希望或不希望控制台进行任何输入或输出的程序,您可以通过重置stdin、stdout和stderr,但这可能会被视为混乱和有点激烈

  • 与中一样,您可以更改主线程的默认异常处理程序,以便将故障转移到SLF4J而不是stderr。但是,您可能仍然无法恢复:当您捕获线程中的异常时,没有其他地方可以恢复执行


考虑到这一点,我根据将jul-to-slf4j.jar添加到我的类路径中,并遵循中的编程安装步骤。不幸的是,这没有帮助。我将尝试创建一个这个问题的易于运行的示例。谢谢,我能够做一个快速测试,从您提到的SO问题中获取一些代码,这确实允许我将错误记录到文件中。这个文件没有显示在日志文件中,我最大的问题是程序实际上没有终止,因为有些类创建了线程。因为我没有任何控制台输出,所以我无法诊断为什么某些东西不能按预期工作(直到我重定向标准错误)。