During the development of eosgi-e4-plugin, the following question was raised: How can we shut down the started OSGi container in the way that shutdown hooks are called?
I did a lot of searching, but could not find a satisfiable solution. Let’s see what I have found.
Executing kill command
There is the option to call kill command on Unix systems and send SIGINT or SIGTERM to the JVM. The problems with this:
- I do not want to execute one more process just to kill another one if not necessary
- There is no such command on Windows. There is no command in windows that can send SIGINT or SIGTERM to a process
Using JNA and Native calls
Another option is to use JNA. This works pretty well in Linux, but Windows is still a problem. One can call WM_CLOSE on every window of an application or send a Ctrl+C event to the console of the running process, but there is no solution if the running program neither has a console nor a window. That is the case when a process is started with Eclipse Launcher. The console of the application is redirected; therefore external process cannot send CTRL events to it.
Trick: Use Attach API and a dynamically installed Java Agent
When a programmer calls System.exit(int) or Runtime.getRuntime().exit(int) within a java process, it starts clean shutdown procedure where all of the shutdown hooks are called. The goal is to force a code snippet in the target JVM to call the exit method. How to do that?
With Java Attach API it is possible to connect to any JVM that runs on the same host. It is also possible to load a Java Agent into the connected JVM. What if the Java Agent calls the exit method? That is possible. I tested it and it works well.
- what exit code should be used for the standard shutdown procedure
- should the JVM shut down forcibly with a different exit code if the standard shutdown procedure does not end within a timeout? This can happen if a non-daemon thread is locked.
Feel free to use this technique and let us know if it worked for you!