找出谁调用jvm shutdown hook

时间:2017-02-07 13:48:54

标签: java jvm shutdown-hook

我有基于Java的Windows桌面应用程序。

我在应用程序中保留了defaultuncaughtexceptionahandler和shutdown hook。

我有一些用户称为退出点,例如,用户点击退出,某些错误条件等。所有用户出口点都有正确的日志,后面会有登录关闭钩子。

现在,对于我的一位用户,应用程序会不时退出。这里用户没有调用任何用户出口点。打印关闭挂钩日志。 defaultuncaughtexception处理程序没有异常。

我无法找到谁调用system.exit以及因此关闭钩子。 我能以某种方式找到调用shutdown hook或system.exit()的内容吗? 关闭钩子的打印让我觉得这是一个合适的jvm关闭而不是一个突然的。

最诚挚的问候, Saurav

2 个答案:

答案 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等外部事件也是如此。