Is there any way we can execute some java code when a jvm process is killed?

StackOverflow https://stackoverflow.com/questions/23487489

  •  16-07-2023
  •  | 
  •  

Question

We want to execute some java code or shell code before a JVM exits when it is killed manually. Our application is not running in a container. We need to monitor it automatically using the Java code itself or some command line tool.

Était-ce utile?

La solution

You can add a shutdown hook by using Runtime.getRuntime().addShutdownHook(). Such a shutdown hook is run by the JVM, once the JVM' process terminates. However, note that this is not always the case. A JVM might get killed before it gets the chance to trigger its shutdown hooks. This is mentioned in the javadoc:

In rare circumstances the virtual machine may abort, that is, stop running without shutting down cleanly. This occurs when the virtual machine is terminated externally, for example with the SIGKILL signal on Unix or the TerminateProcess call on Microsoft Windows. The virtual machine may also abort if a native method goes awry by, for example, corrupting internal data structures or attempting to access nonexistent memory. If the virtual machine aborts then no guarantee can be made about whether or not any shutdown hooks will be run.

You can use a shut down hook as follows:

Runtime.getRuntime().addShutdownHook(
  new Thread("app-shutdown-hook") {
    @Override 
    public void run() { 
      System.out.println("bye"); 
    }
});

You can and should also deregister a shut down hook once it is no longer required. Otherwise, the JVM can never garbage collect the hook.

Autres conseils

Not sure what you mean by "killed"?

If it is by a signal, it depends on the signal. For some of these you can add a JVM shutdown hook which the JVM will execute... But not all. SIGKILL is instant death for instance.

With shell code you can do that:

my java command;
# inspect $?

Run that as a background process; you can tell whether the JVM was killed by inspection of $? since it will be 128 or greater (127 + number of signal used to kill).

Note that you can BOTH capture the command output if needed AND inspect $?:

output=$(my java command);
# inspect $? -- ONLY THEN inspect $output

Of course, add quotes where appropriate etc etc.


And of course you can also store the value of $? before inspecting it later:

my command;
RC=$?;
# do something else
# inspect $RC

Finally, it is important to note that in custom code which uses System.exit() you should avoid exiting with 1: the JVM will exit with that return code whenever main() throws anything.

Please see this post. You just have to tell the runtime you want to execute it at the end of everything. Tada.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top