java - Java 程序如何检测到 MacOS 机器正在关闭?

标签 java macos daemon

我有一个 Java 应用程序,每当我启动机器时,我都想在我的 Mac 上启动它。每当机器关闭时,应用程序应正常关闭。
我在 main 方法中添加了一个关闭钩子(Hook):

Runtime.getRuntime().addShutdownHook(new Thread(new ShutdownHook(scheduler)));
ShutdownHook类看起来像这样:
public class ShutdownHook implements  Runnable {
    private final static Logger LOGGER = LoggerFactory.getLogger("Shutdown Hook");
    private final Scheduler scheduler;

    public ShutdownHook(Scheduler scheduler) {
        this.scheduler = scheduler;
    }

    @Override
    public void run() {
        LOGGER.debug("Starting to shot down the application");
        try {
            scheduler.shutdown();
        } catch (final SchedulerException e) {
           LOGGER.error("An error occurred while trying to shut down the scheduler", e);
        }
        LOGGER.info("Exiting the shutdown hook");
    }
}
然后我将应用程序构建到一个可执行 JAR 中,并将其添加到“登录项”列表中。
"Users and Groups" window
该应用程序在我登录时启动。
但是,当机器关闭时,不会执行关闭钩子(Hook)。
如何确保当我使用下面显示的菜单项关闭机器时,正在运行的 Java 应用程序检测到机器正在关闭?
"Shutdown" menu item
更新 1:
据我了解,修复错误的一种方法是使用 launchd启动Java程序。我写了 plist下面的文件。
下一个问题是如何确保launchd运行 plist 中描述的应用程序文件?
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>ExitTimeOut</key>
    <integer>300</integer>
    <key>StandardErrorPath</key>
    <string>/Users/XXXXXX/sw/wordcounter-daemon/error</string>
    <key>Label</key>
    <string>com.dpisarenko.wordcounterdaemon</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/bin/java</string>
        <string>-jar</string>
        <string>/Users/XXXXXXX/sw/wordcounter-daemon/wordcounter-daemon-0.1-jar-with-dependencies.jar</string>
    </array>
</dict>
</plist>

最佳答案

通常 Unix 风格的系统会关闭 a daemon process分两步:

  • SIGTERM信号发送到进程
  • SIGKILL如果进程在点 1 后 X 秒后仍在运行,则信号发送到进程

  • This answer解释如何配置 ExitTimeOut在 MacOS 上控制这两个信号之间时间的值。
    非守护进程的行为可能不同,这可能是您的进程未执行 JVM 关闭 Hook 的原因。 JVM 可能收到 SIGKILL并且按照设计,用户空间进程无法处理此信号。您可能希望将您的进程转换为守护进程。

    关于java - Java 程序如何检测到 MacOS 机器正在关闭?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68429985/

    相关文章:

    java - 将类路径传递给 buildr 中基于 java/scala 的项目中的自定义任务

    java - 字符串...对象被称为什么?

    java - JSP 下载后删除文件

    macos - 如何在 osx 上分发 .net core 2.0 控制台应用程序

    XCode 4 我可以将下载从一台机器复制到另一台机器吗

    具有日志功能的 c Pipes shell 守护进程无法正常工作

    daemon - JGit:如何使用 InMemoryRepository 来了解 dfs 实现

    java - DynamoDB 如何查询强一致性的非键属性?

    macos - 使 Root View Controller 在 mac OSX swift 中消失

    python - 使用 pep-3143 创建 python 2.7 守护进程