Handling abnormal Java program exits - java

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?

Related

Run code on application crash

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.

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 do I use swing in a shutdown hook?

Is there any possible way to add swing into a shutdown hook (that is, display a popup upon the VM shutting down)?
I realize that if I try to make a new JFrame, it will give me an error, as it tries to register a shutdown hook, which fails as the VM is already shutting down. I'm just wondering if there is in fact any way around this
You really shouldn't be doing this. From the Runtime.addShutdownHook specification:
The Java virtual machine shuts down in response to two kinds of events:
The program exits normally, when the last non-daemon thread exits or when the exit (equivalently, System.exit) method is invoked, or
The virtual machine is terminated in response to a user interrupt, such as typing ^C, or a system-wide event, such as user logoff or system shutdown.
...
Shutdown hooks run at a delicate time in the life cycle of a virtual machine and should therefore be coded defensively. They should, in particular, be written to be thread-safe and to avoid deadlocks insofar as possible. They should also not rely blindly upon services that may have registered their own shutdown hooks and therefore may themselves in the process of shutting down. Attempts to use other thread-based services such as the AWT event-dispatch thread, for example, may lead to deadlocks.
Shutdown hooks should also finish their work quickly. When a program invokes exit the expectation is that the virtual machine will promptly shut down and exit. When the virtual machine is terminated due to user logoff or system shutdown the underlying operating system may only allow a fixed amount of time in which to shut down and exit. It is therefore inadvisable to attempt any user interaction or to perform a long-running computation in a shutdown hook.
...
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.
Specific warnings here that suggest you not do this:
"Shutdown hooks should also finish their work quickly."
Relying on anything that might take a while to do its work, or blocking indefinitely on user-input like JOptionPane dialogs, is not what you should be doing in your shutdown hook.
"Attempts to use other thread-based services such as the AWT event-dispatch thread, for example, may lead to deadlocks"
Swing runs on-top of AWT, whose underlying event-dispatch thread may be in the process of shutting down, too. Trying to use Swing or AWT while shutting down can lead not only to dead locks but also may just not work at all, anyways.
"If the virtual machine aborts then no guarantee can be made about whether or not any shutdown hooks will be run"
There are no guarantees your user could even possibly get your message, since shutdown hooks are only guaranteed to run when it exits normally or terminated -- not when halted or aborted.
Shutdown hooks are supposed to execute as quickly as possible. That does not include waiting for a user to confirm a dialog. In any case you have no guarantee that the Swing event thread is still running.
You can't do this.
If there is, it won't help you.
The shutdown hooks are invoked asynchronously as part of the JVM shutdown, so a "confirm" dialog won't really confirm anything as you can't halt or reverse the shutdown process. Waiting for a user to make a decision is not the kind of action a shutdown hook is meant for. A shutdown hook in an interactive program does not make sense.
The real use case for shutdown hooks is:
for releasing resources and other housekeeping when the JVM shutsdown
It is also important to note the shut down hook wont always be run, for more see my answer here: How to shutdown java application correctly from C# one
Swing GUI must be done on Event Dispatch Thread, then
Create JDialog or JOptionPane on Initial Thread
Show Container
Call for Shutdown Hook
Simple way, but required end user action (close JDialog)
I'm not sure about your question, but I think its impossible to run or display a popup window when JVM is shutting down. Its like your trying to run while preparing to sleep? Just guessing. :)

Categories

Resources