Run code on application crash - java

I want to run a block of code whenever my server crashes. However, the only way I can think about is to write a client checking if there's open for connections.
Are there any way I can write some code on the actual server, being run just before the server shuts down?

Shut down and crash are two very different things. You can have shutdownHook for JVM standard exit, but nothing for the case of crash which means +- nuke to the JVM.
The DOC says:
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.
If shutdown hook is not sufficient you'll need to monitor the app externally.

Related

Is there is an oposite tool to static initializer in Java

Static blocks are executed when class is loading even before the public static void main starts. Is there any possibility to run a certain code just before the program close?
I think you're looking for Runtime.addShutdownHook. It's not a language level construct in the way that static initializer blocks are, but I think it'll do what you want.
You should be careful with shutdown hooks though - see the documentation for various warnings around them.
From Runtime.addShutdownHook:-
Just to add a point to Jon Skeets answers
A shutdown hook is simply an initialized but unstarted thread. When
the virtual machine begins its shutdown sequence it will start all
registered shutdown hooks in some unspecified order and let them run
concurrently. When all the hooks have finished it will then run all
uninvoked finalizers if finalization-on-exit has been enabled.
Finally, the virtual machine will halt. Note that daemon threads will
continue to run during the shutdown sequence, as will non-daemon
threads if shutdown was initiated by invoking the exit method.
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.

How do you tell when a program is being terminated?

So I'm working on a command-line server program that has to handle user stats and other data, and I have a command to stop the server and save user stats and the data to a file. What I want to know is if there is a way to also save user stats and data when the server is terminated without using the stop command. I tried creating a new process and finding when the process is terminated, but it didn't tell me when the server was being terminated. Is there any solution?
I assume you're talking about a situation where someone Ctrl+C's the program, or terminates the program in an unexpected way. The best way I know to handle this situation is to use a Shutdown Hook.
From the documentation:
When the virtual machine begins its shutdown sequence it will start all registered shutdown hooks in some unspecified order and let them run concurrently
But there's a chance this won't work for you because as the documentation also says:
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.

How to ensure a piece of code is run before exiting a java application

I'm using a licensed API which has a method to acquire/release a license object from a license server that has a finite number of licenses. At the beginning of my application, I call the method to acquire the license, but I want to make sure that this gets released even if my program terminates/crashes abruptly (exceptions, SIGTERM, etc). Is the shutdown hook the best way to approach this issue?
#thedan is correct about hard JVM crashes. If a JVM crashes hard or it gets a SIGKILL, it won't get a chance to run anything before exiting. There is nothing you can do to remedy this in Java in that scenario. (But the situation is the same in other languages too ...)
However if the JVM does an orderly shutdown in response to all non-dameon threads ending, calling System.exit(), getting a SIGINT and so on, then the JVM will attempt to run the shutdown hooks. There is more information on Java's shutdown hook mechanisms in the Q&A page and the javadocs.
The finally approach is also an option, but is only works if the thread in question is terminated before the JVM exits. This won't happen if System.exit() is called or the JVM is terminated by a signal. Shutdown hooks work in more situations.
(To my mind, finally is really for performing clean on a single thread rather than for the entire application. However if your application consists of just one thread ... or if it has a master thread that is responsible for orderly shutdown ...then finally can serve the purpose of application cleanup.)
The real solution is to configure the licensed API so that the license manager can detect when the application instance using a license goes away without releasing it. Whether this is possible depends on the license manager.
If the program is terminated through a crash of the JVM, you can't rely on anything being called.
If the program is terminated through an exception that doesn't involve the JVM you should be able to wrap everything in a try/catch/finally block. Any code in the finally block would be guaranteed to run before your code exits.
For exceptions, you can wrap the body of main in a try/catch/block. For handling the SIGTERM signal, you can add a shutdown hook. However, the shutdown hook is not guaranteed to get triggered for a signal like SIGKILL.
From Java doc:
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 achieve this by never calling Sytem.exit().
In main() you create a "last line of defense" with
try {
startApp();
} catch (Exception ex) {
// do some logging
} finally {
releaseLicense();
}

How to deal with ^C in JVM console applications?

When a JVM-ran (written in Scala actually, but I tend to believe that the solution is going to be pretty much the same for Groovy, Clojure or pure Java) console program of mine gets terminated by the user pressing Ctrl+C (or by the system shut-down sequence, I don't know if there is any difference for a program), how do I make sure the external resources the application modifies (databases, files, web service abstracted resources) are left in a predictable, non-logically-corrupt state?
You can try to implement a shutdown hook as others pointed BUT:
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.
I guess, you would have to introduce transactional context into your application I believe. For databases that's quite easy, for file system you can look into Apache Commons Transaction
Take a look at Runtime.addShutdownHook.
You would typically use it as so:
Runtime.addShutdownHook(new Thread() {
public void run() {
// do your clean up here.
}
});
You can trap this signal and close off resources. Most services do not need to be closed gracefully, however files you write to usually do.
It is possible just adding a shutdown hook is all you need. But I would test this for your situation.

Handling abnormal Java program exits

Suppose I have a Java application that opens a database connection. Normally I would add a connection.close() in a finally block, but this block wouldn't be executed in the case of a kill operation, or any other abnormal termination, would it? Are there any other precautions that I, as a programmer, can make in order to close the connection properly before the application exits?
You should look at the Runtime.addShutdownHook() method for Java (http://java.sun.com/javase/6/docs/api/java/lang/Runtime.html#addShutdownHook(java.lang.Thread)). It allows you to add a hook that will be called when the virtual machine terminates. You can use it to call a cleanup routine.
That would be for a TERM signal though. A KILL signal will kill the process and not allow it to do any cleanup (because the KILL signal cannot be caught or ignored by the receiving process).
If something external kills your program, there's nothing you can do about it. Obviously they wanted to stop it, so how can you prevent them?
I was going to suggest a shutdown hook, but the Javadocs state:
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.
(emphasis mine)
Killing a program will eventually timeout a TCP stream from your program to your [Oracle|SQL Server|MySQL|PostgreSQL] server.
The server will see it and rollback any pending transactions.
You shouldn't need to call connection.close() on application shut-down, since all open files will be closed automatically by the operating system.
Also, the Connection's finalize() method should be run before application shut-down automatically (if the shut-down is normal, not ABORTed), and that should close the connection.
In any case, you can register shutdown-hooks, to do any clean-up you require (again, will be run in normal shutdown cases, not ABORTs).
When you really get killed (kill -9 on UNIX), you can not do anything against that.
A finally-block is the most you can do, see SO: In Java, is the “finally” block guaranteed to be called (in the main method)? for details.
Some level of abnormal termination is unavoidable. How would you catch the event of the power cable being pulled on the server?

Categories

Resources