有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java跟踪“隐藏”异常

我正在检查我的一个程序的输出,在这个程序中,我不时看到一条类似“java.lang.NullPointerException”的消息,而没有其他消息。因为这不是来自我的代码,我很确定,有一些第三方库,其中一些混蛋做了一些类似于:catch(ex){println ex.getMessage()}的事情

是否有办法重新启用堆栈跟踪报告并查看问题发生的位置?通过调试器+逐步执行来实现这一点并不容易,因为当我在一大组输入数据上运行程序时,问题是随机发生的,而如果我试图在看起来有罪的数据片上重新运行程序,则无法再现问题

提前谢谢


共 (2) 个答案

  1. # 1 楼答案

    更新:您最好在发现的异常上使用IDE断点

    否则,您可以通过System.setOut(..)设置一个自定义PrintStream,并且在那里,每当打印某些内容时,也打印Thread.currentThread().getStackTrace()

    理想情况下,您的PrintStream应该只包装原始的System.out并发送给它。比如:

    public class PrintStreamWrapper extends PrintStream {
        public PrintStreamWrapper(OutputStream out) {
           super(out);
        }
    
        public void println(String x) {
             StackTraceElement[] trace = Thread.currentThread().getStackTrace();
             // print everything, but not to the System.out, 
             // because you'll end up in a loop.
             super.println(x);
        }   
    }
    

    然后,在课程开始时:

    System.setOut(new PrintStreamWrapper(System.out));
    
  2. # 2 楼答案

    没有看到代码,很难说。如果频繁抛出异常,热点编译器实际上可能会对周围的代码进行过多优化,以至于VM无法生成正确的堆栈跟踪,异常#printStackTrace()将只打印异常的类名和消息

    在执行更多操作之前,我将尝试使用-XX:-OmitStackTraceInFastThrow VM参数运行应用程序,以强制VM为所有异常创建适当的堆栈跟踪