我有基于Java的Windows桌面应用程序。
我在应用程序中保留了defaultuncaughtexceptionahandler和shutdown hook。
我有一些用户称为退出点,例如,用户点击退出,某些错误条件等。所有用户出口点都有正确的日志,后面会有登录关闭钩子。
现在,对于我的一位用户,应用程序会不时退出。这里用户没有调用任何用户出口点。打印关闭挂钩日志。 defaultuncaughtexception处理程序没有异常。
我无法找到谁调用system.exit以及因此关闭钩子。 我能以某种方式找到调用shutdown hook或system.exit()的内容吗? 关闭钩子的打印让我觉得这是一个合适的jvm关闭而不是一个突然的。
最诚挚的问候, Saurav
答案 0 :(得分:3)
如果您怀疑有人明确调用了System.exit(…)
或类似的功能,您可以使用SecurityManager
拦截它:
System.setSecurityManager(new SecurityManager() {
@Override
public void checkExit(int status) {
new Exception("exit attempt with return code "+status).printStackTrace();
}
// note that all dedicated check... methods delegate to the two below,
// so overriding these is sufficient to enable all other actions
@Override
public void checkPermission(Permission perm, Object context) { }
@Override
public void checkPermission(Permission perm) { }
});
但是,这不会拦截由外部事件引起的关闭,如TERM信号等。
答案 1 :(得分:2)
如果您正在运行OpenJDK / Oracle JDK,您可以注册一个“系统”关闭挂钩,它将转储已启动关闭进程的线程:
sun.misc.SharedSecrets.getJavaLangAccess().registerShutdownHook(7, true,
() -> {
System.out.println(Thread.currentThread());
new Exception("Who called me?").printStackTrace();
});
即使对于Ctrl+C
等外部事件也是如此。