当包装器异常有消息时,带有Log4j的Slf4j不会打印包装异常(由...引起)

Dra*_*vic 6 java logging log4j exception slf4j

第一个例子:

public class Main {

    private static final Logger logger = LoggerFactory.getLogger(Main.class);

    public static void main(String[] args) throws Exception {
        try {
            throw new RuntimeException(new NullPointerException("NPE"));
        } catch (RuntimeException e) {
            logger.error("Error:", e);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

Error:
java.lang.RuntimeException: java.lang.NullPointerException: NPE
    at Main.main(Main.java:10)
Run Code Online (Sandbox Code Playgroud)

在第二个例子中,我们只是添加一条消息RuntimeException:

throw new RuntimeException("RTE", new NullPointerException("NPE"));
Run Code Online (Sandbox Code Playgroud)

输出:

Error:
java.lang.RuntimeException: RTE
    at Main.main(Main.java:10)
Run Code Online (Sandbox Code Playgroud)

为什么NullPointerException不记录这种情况?

注意:e.printStackTrace()在两种情况下都会打印两个例外:

java.lang.RuntimeException: RTE
    at Main.main(Main.java:10)
Caused by: java.lang.NullPointerException: NPE
    ... 1 more
Run Code Online (Sandbox Code Playgroud)

版本:

slf4j-api: 1.7.12
slf4j-log4j12: 1.7.12
log4j: 1.2.17
Run Code Online (Sandbox Code Playgroud)

Nam*_*man 6

给我一个可能尝试使用所有文档和我可以调试,我希望这有助于以任何方式:

  @param message the message object to log.
  @param t the exception to log, including its stack trace.
  public void error(Object message, Throwable t) 
Run Code Online (Sandbox Code Playgroud)

因此,两种情况都包括代码语句抛出的RuntimeException的堆栈跟踪.差别不大.

案例1:throw new RuntimeException(new NullPointerException("NPE"));

RuntimeException引用Java-DocNullPointerException Java-Doc

public RuntimeException(Throwable cause)
Run Code Online (Sandbox Code Playgroud)

使用指定的cause和详细消息(cause==null ? null : cause.toString())(通常包含cause的类和详细消息)构造一个新的运行时异常.此构造函数对于运行时异常非常有用,这些异常只是其他throwable的包装器.


public NullPointerException(String s)
Run Code Online (Sandbox Code Playgroud)

使用指定的详细消息构造NullPointerException.


所以这可能是回答你的问题,其中的第一部分java.lang.RuntimeException执行中被抛出,这是造成new NullPointerExceptioncause==null计算结果为cause.toString()印即java.lang.NullPointerException现在因为这个异常本身已经通过一条消息,如下为NPE

注意:您在代码中已将原因称为NullPointerException.(因此cause==null计算结果为false)

案例2:throw new RuntimeException("RTE", new NullPointerException("NPE"))

public RuntimeException(String message, Throwable cause)
Run Code Online (Sandbox Code Playgroud)

使用指定的详细消息和原因构造新的运行时异常.请注意,与cause关联的详细消息不会自动合并到此运行时异常的详细消息中.


在这种情况下,你最终会java.lang.RuntimeException被抛出一条消息,RTE因为你的原因是他RuntimeException自己的孩子而且父亲被抓住了,它被执行并且在这种情况下没有达到孩子.

  • 很好的分析,谢谢。有什么方法可以让 log4j 打印整个堆栈跟踪? (2认同)

Dra*_*vic 6

我注意到在log4j.properties我正在使用的文件中有以下行:

log4j.throwableRenderer=org.apache.log4j.EnhancedThrowableRenderer
Run Code Online (Sandbox Code Playgroud)

caused by当记录异常时,似乎导致元素被省略.

删除后,将记录完整堆栈跟踪.

  • 很高兴知道。但这引起了我心中的疑问,我没有在我的“log4j.properties”中使用这一行(“log4j.throwableRenderer=org.apache.log4j.EnhancedThrowableRenderer”),并且仍然没有记录整个堆栈跟踪。我应该做出哪些改变? (2认同)