Java 当包装异常有消息时,带有Log4j的Slf4j不会打印包装异常(由引起)
第一个例子:Java 当包装异常有消息时,带有Log4j的Slf4j不会打印包装异常(由引起),java,exception,logging,log4j,slf4j,Java,Exception,Logging,Log4j,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("NP
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);
}
}
}
输出:
Error:
java.lang.RuntimeException: java.lang.NullPointerException: NPE
at Main.main(Main.java:10)
Error:
java.lang.RuntimeException: RTE
at Main.main(Main.java:10)
Exception in thread "main" java.lang.RuntimeException: java.lang.NullPointerException: NPE // Here, "java.lang.NullPointerException: NPE" - this portion is used as message according to RuntimeException
at Main.main(Main.java:3)
Caused by: java.lang.NullPointerException: NPE
... 1 more
Exception in thread "main" java.lang.RuntimeException: RTE // Here "RTE" is used as message
at Main.main(Main.java:3)
Caused by: java.lang.NullPointerException: NPE
... 1 more
在第二个示例中,我们只需将一条消息添加到RuntimeException
中:
throw new RuntimeException("RTE", new NullPointerException("NPE"));
输出:
Error:
java.lang.RuntimeException: java.lang.NullPointerException: NPE
at Main.main(Main.java:10)
Error:
java.lang.RuntimeException: RTE
at Main.main(Main.java:10)
Exception in thread "main" java.lang.RuntimeException: java.lang.NullPointerException: NPE // Here, "java.lang.NullPointerException: NPE" - this portion is used as message according to RuntimeException
at Main.main(Main.java:3)
Caused by: java.lang.NullPointerException: NPE
... 1 more
Exception in thread "main" java.lang.RuntimeException: RTE // Here "RTE" is used as message
at Main.main(Main.java:3)
Caused by: java.lang.NullPointerException: NPE
... 1 more
为什么在这种情况下,NullPointerException
没有记录
注意:e.printStackTrace()
在两种情况下都会打印两个异常:
java.lang.RuntimeException: RTE
at Main.main(Main.java:10)
Caused by: java.lang.NullPointerException: NPE
... 1 more
版本:
slf4j-api: 1.7.12
slf4j-log4j12: 1.7.12
log4j: 1.2.17
尝试使用我能使用的所有文档和调试,我希望这能在任何方面有所帮助:
@param message the message object to log.
@param t the exception to log, including its stack trace.
public void error(Object message, Throwable t)
因此,这两种情况都包括代码语句引发的RuntimeException的堆栈跟踪。差别不大
案例1:抛出新的RuntimeException(新的NullPointerException(“NPE”)代码>
public RuntimeException(String message, Throwable cause)
引用和
构造具有指定原因和
(cause==null?null:cause.toString())的详细信息
通常包含原因的类别和详细信息)。这
构造函数对于比
其他一次性用品的包装
使用指定的详细信息构造NullPointerException
因此,这可能回答了问题的第一部分,即在执行过程中抛出java.lang.RuntimeException
,这是由新的NullPointerException
引起的,但当原因==null
计算为false时,原因.toString()
已打印,即java.lang.NullPointerException
,现在由于此异常本身传递了一条消息,如下所示NPE
注意:您在代码中提到了原因为NullPointerException(因此cause==null
计算结果为false)
案例2:抛出新的运行时异常(“RTE”,新的NullPointerException(“NPE”)
public RuntimeException(String message, Throwable cause)
使用指定的详细信息构造新的运行时异常
和原因。请注意,与原因关联的详细信息不存在
自动合并到此运行时异常的详细信息中
在这种情况下,您最终会得到java.lang.RuntimeException
被抛出的消息RTE
,因为您的原因是RuntimeException
本身的子项,并且父项首先被捕获,在这种情况下,它会被执行,并且不会到达子级。在集群模式下运行的Apache Spark应用程序中使用Slf4j Logger时,我遇到了类似的问题。正如我发现的,在我的案例中,问题是由JVM优化引起的,该优化与省略stackTraceInFastThrow
相关,它基本上并没有打印整个堆栈,只是顶层错误,没有任何细节
在您的情况下,这可能是从NullPointerException
隐藏错误消息。在启动应用程序时,尝试将此参数添加到JVM-XX:-忽略StackTraceInFastThrow
,并让我们知道它是否有效。有两个问题。
为什么在这种情况下不记录NullPointerException[抛出新的RuntimeException(“RTE”,新的NullPointerException(“NPE”);]
答复:
实际上,SLF4J对这种情况没有影响。这纯粹是JVM问题。在JVM中,需要在调用函数之前计算每个传递的参数。如果您遵循这两个示例,就可以很容易地理解这个问题
示例1:
public class Main {
public static void main(String[] args) {
throw new RuntimeException(new NullPointerException("NPE"));
}
}
public class Main {
public static void main(String[] args) {
throw new RuntimeException("RTE", new NullPointerException("NPE"));
}
}
输出:
Error:
java.lang.RuntimeException: java.lang.NullPointerException: NPE
at Main.main(Main.java:10)
Error:
java.lang.RuntimeException: RTE
at Main.main(Main.java:10)
Exception in thread "main" java.lang.RuntimeException: java.lang.NullPointerException: NPE // Here, "java.lang.NullPointerException: NPE" - this portion is used as message according to RuntimeException
at Main.main(Main.java:3)
Caused by: java.lang.NullPointerException: NPE
... 1 more
Exception in thread "main" java.lang.RuntimeException: RTE // Here "RTE" is used as message
at Main.main(Main.java:3)
Caused by: java.lang.NullPointerException: NPE
... 1 more
这里,“java.lang.NullPointerException:NPE”
-这一部分根据RuntimeException用作消息,RuntimeException也是从另一个异常生成的
示例2:
public class Main {
public static void main(String[] args) {
throw new RuntimeException(new NullPointerException("NPE"));
}
}
public class Main {
public static void main(String[] args) {
throw new RuntimeException("RTE", new NullPointerException("NPE"));
}
}
输出:
Error:
java.lang.RuntimeException: java.lang.NullPointerException: NPE
at Main.main(Main.java:10)
Error:
java.lang.RuntimeException: RTE
at Main.main(Main.java:10)
Exception in thread "main" java.lang.RuntimeException: java.lang.NullPointerException: NPE // Here, "java.lang.NullPointerException: NPE" - this portion is used as message according to RuntimeException
at Main.main(Main.java:3)
Caused by: java.lang.NullPointerException: NPE
... 1 more
Exception in thread "main" java.lang.RuntimeException: RTE // Here "RTE" is used as message
at Main.main(Main.java:3)
Caused by: java.lang.NullPointerException: NPE
... 1 more
此处“RTE”
用作消息
在代码中,您使用了3次异常。这不是好的编码
为什么e.printStackTrace()在这两种情况下都打印这两个异常
e.printStackTrace()
将此可丢弃文件及其回溯打印到标准错误流。它在错误输出流上打印此可丢弃对象的堆栈跟踪,该错误输出流是字段System.err的值
由于您的输出是:
java.lang.RuntimeException: RTE
at Main.main(Main.java:10)
Caused by: java.lang.NullPointerException: NPE
... 1 more
- 输出
[“java.lang.RuntimeException:RTE”]
包含此Throwable的toString()方法的结果
反对
- 剩余的行表示以前通过该方法记录的数据
- 具有初始化的非空原因的可丢弃的回溯
通常应包括原因的回溯。格式
这些信息取决于实施情况。为了你的安全
理解后,请阅读下面的回溯示例:
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more
- “…1”
这些行表示此堆栈的剩余堆栈跟踪
“异常”与从屏幕底部指定的帧数相匹配
由此异常引起的异常的堆栈跟踪
(“封闭”例外)
资源链接:
对于SLF4J
,您可以通过
模块将所有呼叫重定向到System.out
和
System.err
到SLF4J定义的记录器,该记录器的名称为
System.out.println
(或类似)调用
在可配置的级别上创建
允许以在确定的级别进行日志记录
运行时
而不是编译时
我注意到在我使用的log4j.properties
文件中有以下行:
log4j.throwableRenderer=org.apache.log4j.EnhancedThrowableRenderer
它似乎导致在记录异常时忽略由
元素引起的
删除后,将记录完整的堆栈跟踪。很好的分析,谢谢。有没有办法让log4j打印整个堆栈跟踪?没有,printStackTrace
在这两种情况下都包含完整跟踪。日志记录不会影响公共关系