【问题标题】:javaagent, systray and shutdownjavaagent、系统托盘和关机
【发布时间】:2012-12-19 14:54:31
【问题描述】:

我们编写了一个 java 代理,其中包括使用 java.awt.TrayIcon 提供某种 GUI。当我们使用这个代理时,例如Tomcat,我们有以下问题:

  1. 用户使用 shell 脚本启动 Tomcat
  2. 我们的代理将图标添加到系统托盘
  3. 用户使用 shell 脚本关闭 Tomcat
  4. AWT 事件线程看到,仍然有可显示的组件、系统托盘图标,并且没有退出
  5. 由于 AWT 事件线程是非守护线程,整个应用程序无法退出

现在的问题是,我们应该怎么做才能让应用程序关闭?是否可以制作 AWT 事件调度线程守护进程?代理是否有关闭挂钩?还有什么?

【问题讨论】:

    标签: java awt systray javaagents


    【解决方案1】:

    为了完整起见,我是这样解决这个问题的:

    我已经启动了另一个守护线程来执行该作业,它会定期检查可显示的 AWT 组件。如果只剩下一个,那就是我的系统托盘图标,那么我将其删除。这允许 AWT 子系统退出,从而导致整个应用程序正常退出。

    【讨论】:

      【解决方案2】:

      您可以尝试添加一个关闭挂钩 (Runtime.getRuntime().addShutdownHook()) 来调用

      SystemTray.getSystemTray( ).remove( trayIcon );

      【讨论】:

      • 不幸的是,关闭钩子从未被调用,因为 JVM 实际上并没有关闭。正是 AWT 事件线程“强制”它继续运行。
      • 您使用的是什么操作系统?在 *ix 上,一个 SIGTERM 触发关闭钩子,一个 SIGKILL 强制终止 JVM,尽管有任何非守护进程运行线程。
      • 是的,但我不是在谈论强行杀死或终止 JVM。问题是如何让 JVM 在 main 方法退出时自然退出。因为没有调用shutdown hook,所以当main方法退出但有非守护线程仍在运行时。
      • 那为什么不直接删除你的 AWT 资源(比如 main 方法末尾的 SystemTray.getSystemTray( ).remove( trayIcon );。顺便说一句,当 JVM正常退出时会调用关闭挂钩>
      • 1.请重新阅读我的问题。应用程序的主要方法完全不受我的控制。我正在写 java 代理。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-17
      相关资源
      最近更新 更多