Jvm invocation api 允许 c++ 程序内嵌虚拟机,运行 Java 代码。这一块的调试还是比较麻烦的。
IDEA attach debugger
IDEA ctrl+alt+f5 可以附加调试器到现有进程。被调试的虚拟机需添加启动参数:-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
,不然一直卡着显示 frame not available.
附加后也看不到输出,但是可以点侧标栏一个相机按钮,查看当前的代码运行位置。
IDEA 运行 java,java中再用ProcessBuilder启动子进程,启动exe。exe 再通过 invocation api 调用 java 代码。
此法可直接在运行窗口查看子进程的log输出。无需额外加载log文件。
需要在启动子进程后,开两个线程,分别读取 子进程 的错误和一般输出。
commands.add("D:\\Code\\FigureOut\\Textrument\\plugins\\DirectUILib\\bin\\ListViewDemo.exe");
Process proc = new ProcessBuilder(commands).start();
BufferedReader errorResult = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
BufferedReader errorResult1 = new BufferedReader(new InputStreamReader(proc.getInputStream()));
new Thread(() -> {
while (proc.isAlive()) try { _log(errorResult.readLine()); } catch (IOException e) { _log(e); } }).start();
new Thread(() -> {
while (proc.isAlive()) try { _log(errorResult1.readLine()); } catch (IOException e) { _log(e); } }).start();
注意 readLine 是阻塞的,所以要用两个线程。
重定向输出至文件。
有时候需要记录日志文件。可以重定向 System.out
。
然后 IDEA 可以加载外部log文件,显示在普通的输出标签页旁边。但这块bug比较多,有时候log文件读一半卡住,自行摸索吧……
- 打印信息不要含有debug字样
- 信息一行不要过长
UncaughtExceptionHandler 无效
Thread.UncaughtExceptionHandler crashHandler = (t, e) -> _log("uncaughtException::", e);
Thread.setDefaultUncaughtExceptionHandler(crashHandler);
无法捕获 jvm invocation api 中的 Uncaught Exception。遇到错误后没有任何信息,直接跳过了。
就如同无法捕获 junit @Test 代码块 中的 Uncaught Exception。比如运行单元测试:
@Test
public void testbebug() {
Thread.UncaughtExceptionHandler crashHandler = (t, e) -> _log("uncaughtException::", e);
Thread.currentThread().setUncaughtExceptionHandler(crashHandler);
Thread.setDefaultUncaughtExceptionHandler(crashHandler);
_log(10 / 0);
}
竟然没没有输出 uncaughtException::
。
而这样在 main 中运行,
public static void main(String[] args) throws Exception {
new TestPlainDictHunxiao().testbebug();
}
可以正常捕获:
uncaughtException::, java.lang.ArithmeticException: / by zerojava.lang.ArithmeticException: / by zero
at hunxiao.TestPlainDictHunxiao.testbebug(TestPlainDictHunxiao.java:24)
at hunxiao.TestPlainDictHunxiao.main(TestPlainDictHunxiao.java:29)
不知道为什么用 @Test 和 exe 调用时,无法捕获异常。
也就是说通过 Jvm invocation api 调用每一个方法的时候,最好自己 catch 一下,不然出错了一点提示都没有。