4

当有人通过 taskmanager 或 taskkill 控制台命令杀死我的应用程序(java,但这并不重要)时,我如何捕捉到?

我知道我无法在我的应用程序中捕捉到这一点,但也许我可以通过一些与操作系统(当然是 Windows)的挂钩来做到这一点。也许 easyhook 库(http://www.codeplex.com/easyhook)可以帮助我,但我在那里找不到示例。我们的应用程序经常在客户服务器上死掉,我只想知道是谁(或什么)杀死了它。我们确定这不是应用程序问题,似乎 java.exe 进程被 taskmanager 杀死了

4

4 回答 4

2

你可以这样做:

Runtime.getRuntime().addShutdownHook(new Thread() {
  public void run() {
    // run some code
  }
});

如果 VM 在本机代码中崩溃,则不会调用它。如果 VM 停止,它也不会被调用。它也没有告诉你为什么它会关闭。请参阅关闭挂钩 API 的设计。我认为您无法获得比这更多的信息。

过去我经常使用Java Service Wrapper。它是一个单独的进程,用于启动和重新启动 Java 进程并记录它们的输出,如果异常意外终止进程,这将很有用。

于 2010-01-11T08:23:32.203 回答
1

您也可以通过使用两个应用程序来简单地通过 java 应用程序来完成。这就是在许多纯 Java 生产系统中的完成方式

  1. 您的主应用程序将在标准位置创建 .lock 文件并以独占方式锁定它。
  2. 您的其他程序(也许称它为看门人应用程序)将继续对其进行 lock() 调用并继续等待。

  3. 当锁定调用返回时,您可以确定您的主应用程序已终止。现在你可以确定了。

    至于“为什么应用程序被杀死”的问题,从技术上讲,您无法找到(可能是 1 或 2 个场景,但不是所有场景),AFAIK。

于 2010-01-11T08:17:35.987 回答
0

您可以使用将在本地计算机上运行的第二个应用程序并监视您的主应用程序。当主应用程序出现故障时,它可以做一些事情(例如重新启动它,记录事件)c

于 2010-01-11T08:16:52.247 回答
0

没有(标准)方法可以确定您的应用程序何时被任务管理器用 Java 杀死。

通常的方法是让第二个应用程序将主应用程序作为子进程启动(使用ProcessBuilder)。当孩子死亡时,包装器会注意到。对于所有常见的终止原因,System.exit()请在您的主应用程序中设置退出代码。在您的包装器中,检查退出代码。如果它不是您明确设置的,那么有人杀死了该应用程序或由于 VM 错误而崩溃。

要区分这两者,请检查子应用程序的输出并在当前目录中查找 VM 故障转储(无论您的应用程序可能是什么;通常是安装您的应用程序的目录)。

于 2010-01-11T08:26:08.280 回答