有没有办法打印外部Java程序的堆栈跟踪

时间:2015-09-23 12:17:16

标签: java

我想编写一个运行另一个程序B并打印B的堆栈跟踪的java程序A.

我知道我可以使用以下代码打印A的堆栈跟踪

for( i = 0; i < Thread.currentThread().getStackTrace().length; i++ ) {
            System.out.println(Thread.currentThread().getStackTrace()[i].
            getMethodName());
}

但如果我从A

执行它,是否可以打印程序B的堆栈跟踪
Process pr = Runtime.getRuntime().exec("javac B.java");
pr.waitFor();
pr = Runtime.getRuntime().exec("java B").printStackTrace();
 pr.waitFor();

4 个答案:

答案 0 :(得分:0)

简短回答:

NO

LONG ANSWER:

程序A只执行B所做的任何程序。它不知道它是如何在内部做的。 A只能知道关于B的事情是B&#39; s output streamerror stream可以产生的。如果您想了解更多信息(例如,B使用了多少内存等),您可以尝试找到它PID并向操作系统询问一些信息

答案 1 :(得分:0)

JDK包含命令行工具jstack

  

打印Java进程,核心文件或的Java线程堆栈跟踪   远程调试服务器。此命令是实验性的,不受支持。

当你调用jstack时,你需要提供你想要获得stracktrace的Java进程的process id

如果可以从主Java程序运行jstack,则可能需要进行试验。

答案 2 :(得分:0)

是。可以通过另一个(Java)程序以不同的方式访问JVM进程。

访问另一个Java程序的一种非常通用的方法是writing a Java agent /使用Instrumentation API。使用此API,可以通过修改此程序的已执行代码来更改正在运行的Java程序。例如,您可以重新定义现有方法,以包含在达到给定执行点时公开堆栈跟踪的其他指令。或者,您可以简单地指示直接打印堆栈跟踪。这也是how the mentioned JStack application works

更简单的替代方法是从正在运行的应用程序中公开JMX bean,以允许触发堆栈跟踪的打印。

然而,这两种访问模式都需要一些技巧来访问其他VM的进程ID what is not trivial in Java

答案 3 :(得分:0)

您可以考虑编写代理。有一个教程here。代理允许您将代码插入任何正在运行的Java程序中,并查看正在发生的事情。这就是远程调试的工作原理。作为示例,您使用-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n启动JBoss或Tomcat以插入调试代理。您可以通过编写代理然后在启动时将代理插入正在运行的进程来执行相同的操作。

相关问题