1

We write a java agent, which among other things provides some sort of GUI using java.awt.TrayIcon . When we use this agent in, e.g. Tomcat, we have the following problem:

  1. User starts Tomcat using shell script
  2. Our agent adds icon to systray
  3. User shuts Tomcat down using shell script
  4. AWT Event thread sees, that there is still displayable component, systray icon, and does not quit
  5. As AWT Event thread is non-daemon thread, whole application cannot quit

Now the question is, what should we do, to allow an application to shut down? Is it possible to make AWT Event dispatch thread daemon? Is there shutdown hooks for agents? Anything else?

Nikem
  • 5,716
  • 3
  • 32
  • 59

2 Answers2

1

For the sake of completeness, here is how I have solved this problem:

I have started another daemon thread with the job, that periodically checks for displayable AWT components. If there is only one of them left, and that is my systray icon, then I remove it. This allows AWT subsystem to exit resulting in normal exiting of the whole application.

Nikem
  • 5,716
  • 3
  • 32
  • 59
0

You could try adding a shutdown hook (Runtime.getRuntime().addShutdownHook()) which calls

SystemTray.getSystemTray( ).remove( trayIcon );

Bruno Grieder
  • 28,128
  • 8
  • 69
  • 101
  • Unfortunately, shutdown hook is never called, as JVM is not, in fact, shutting down. Precisely the AWT event thread "forces" it continue running. – Nikem Mar 26 '12 at 14:52
  • What OS are you on? On *ix a SIGTERM triggers the shutdown hook(s) and a SIGKILL forcibly terminates the JVM, in spite of any non-daemon running thread. – Bruno Grieder Mar 26 '12 at 15:23
  • Yes, but I am not talking about forcibly killing or terminating JVM. The problem is how to let JVM quit naturally, when main method exits. Because shutdown hook is not called, when main methods exits but there are non-daemon threads still running. – Nikem Mar 26 '12 at 15:31
  • Then why not just remove your AWT resources (like `SystemTray.getSystemTray( ).remove( trayIcon );` at the end of the main method. btw, shutdown hooks are called when the JVM exits *normally* – Bruno Grieder Mar 26 '12 at 15:38
  • 1. Please reread my question. Application's main method is totally out of my control. I am writing java agent. – Nikem Mar 26 '12 at 15:40
  • 2. If main method exits, that does not always mean, that application exits. main method could start others non-daemon "worker" threads. So removing systray icon while application is still running is not what I would like to achieve :( – Nikem Mar 26 '12 at 15:41
  • And, one more time. shutdown hooks are run AFTER all non-daemon threads cease to exist. In my case AWT Event thread runs, so no shutdown hooks are executed. – Nikem Mar 26 '12 at 15:42
  • My bad, I skipped the fact it is a Java agent – Bruno Grieder Mar 26 '12 at 15:52
  • Last try. Can you wrap your app/tomcat with the Java Service Wrapper ? Then you can call `WrapperManager.signalStopping()` from Java of trigger the script kill on the Wrapper. This is how we do it but, in all honesty, our tray is not loaded from a Java agent. – Bruno Grieder Mar 26 '12 at 16:01
  • You can listen to events on the WrapperManager; not sure this will work within a java agent but a kill is normally detected. – Bruno Grieder Mar 26 '12 at 16:10