Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 当包装异常有消息时,带有Log4j的Slf4j不会打印包装异常(由引起)_Java_Exception_Logging_Log4j_Slf4j - Fatal编程技术网

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
    在这两种情况下都包含完整跟踪。日志记录不会影响公共关系