找出谁调用了 jvm shutdown hook

Finding out who calls jvm shutdown hook

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

我在我的应用程序中保留了 defaultuncaughtexceptionahandler 和关闭钩子。

我有一些称为退出点的用户,例如,用户单击退出、一些错误情况等。所有用户退出点都有正确的日志,随后是登录关闭挂钩。

现在,我的一位用户不时退出应用程序。这里用户没有调用任何用户出口点。打印关机挂钩日志。 defaultuncaughtexception 处理程序也不例外。

我找不到调用 system.exit 和关闭挂钩的人。 我能以某种方式找到所谓的关闭挂钩或 system.exit () 吗? 关闭挂钩的打印让我认为这是正确的 jvm 关闭而不是突然关闭。

此致, 索拉夫

如果您怀疑有人显式调用了 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 信号等)引起的关机

如果您是 运行 OpenJDK / Oracle JDK,您可以注册一个 "system" 关闭挂钩,它将转储已启动关闭进程的线程:

    sun.misc.SharedSecrets.getJavaLangAccess().registerShutdownHook(7, true,
            () -> {
                System.out.println(Thread.currentThread());
                new Exception("Who called me?").printStackTrace();
            });

这甚至适用于外部事件,如 Ctrl+C