I'm developing an application that will run as a service. I have added a shutdown hook to the program to do some file cleanup. When I install the program as a service (on Linux as a daemon or as a Windows service) the shutdown hook executes correctly. However, when running in the IDE the shutdown hook is never executed. Is there a way to stop the running process in the IDE and have the shutdown hook execute?
Thanks,
Pablo
Unfortunately there is no way to do this within the current Netbeans system,since the kill methods for both types of app testing (Debug and Normal) both, well kill the process, giving it no chance to cleanup.
Depending on the architecture of your app you may be able to add a System.exit(0) call, but other than that you are stuck with opening it up in the console.
I disagree. A sigkill in unix or terminate process in windows by definition will kill the running process without giving any ability for the application to catch these events. This is necessary to terminate an unresponsive process. These signals should only be used when a process does not respond to a siginit (ctrl c) or a sigterm or end task in windows. NetBeans seems to be sending a sigkill rather than siginit or sigterm. As far as I'm concerned this is bad practice.
There should be a secondary option to kill the process however the primary end process button should be to send siginit or sigterm. Applications should anticipate the user hitting ctrl c or end task on their application and as a best effort cleanly close files/sockets and save persistent/state data. An application should not anticipate a sigkill or terminate process but rather be developed in such a way that a sigkill or terminate process are not necessary.
By NetBeans using these methods as the only means to terminate the application from the IDE is erroneous.
Nope. Don't cleanup your program using shutdown hooks. From the docs...
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.
When the contract says that there is no guarantee that your shutdown hooks will always be called, it is not advisable to use them for critical operations.
Related
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?
Is a Java Process which was created via Runtime.exec killed when the runtime that created the process dies? Or do I have to kill them manually, e.g. by installing a shut down hook and killing all remaining processes via Process.destroy. The javadoc only speaks about what happens when the runtime continues to exist.
A Java Process is created as a subprocess of the JVM. All operating systems that I know of kill subprocesses when the parent process terminates.
However, if the process you create forks its own processes, that are not its child processes (or are detached, e.g. in the case of Windows GUI applications), those may continue running after the JVM terminates. There is an issue possibly related to that described in this question.
I have a Java 1.6 application that accesses a third party native module, through a JNI class provided as the interface. Recently we noticed that a SEGFAULT is occurring in the native module, and is causing our application to crash. Is it possible to catch and handle this event, at least to log it properly before dieing?
I tried both Java techniques in the article from kjp's answer. Neither worked. Attempting to install a signal handler on 'SEGV' results in the exception
Signal already used by VM: SEGV
The shutdown handler I installed simply failed to fire, presumably because of what the IBM article states:
Shutdown hooks will not be run if
Runtime.halt() method is called to terminate the JVM. Runtime.halt() is provided to allow a quick shutdown of the JVM.
The -Xrs JVM option is specified.
The JVM exits abnormally, such as an exception condition or forced abort generated by the JVM software.
If all you want to do is log and notify you can write a script which runs your application. When the application dies, the script can detect whether the application terminated normally and from the hs_errXXXX file which has all the crash/SEGV information and mail it to someone (and restart the application if you want)
What you need to do is to run the faulty JNI code in another JVM and communicate with that JVM using RMI or JMS or Sockets. This way when the library dies, it won't bring down your main application and you can restart it.
Based on several weeks of research at the time, as well as conversations with JVM engineers at a conference this is not possible. The system will not let you install a SignalHandler on the SEGV signal.
More specifically, I have a multithreaded command line Java application which runs and collects data until the user terminates it.
The obvious way for the user to terminate it is by pushing Control-C, but then I need to install a shutdown hook in the VM and deal with all the threads.
Is there a nicer / more appropriate way for the user to inform the application that it's time to shutdown?
For example, is there a way to capture some other key combination and set a boolean flag in my application?
As a further clarification, I seek something functionally similar to signal handling in C.
One way can be to create a new thread which will "listen" to standard input. Based on whatever key pattern you decide, that thread can set the flag in the main application.
Consider using shutdown hook like this:
Runtime.getRuntime().addShutdownHook(shutdownHook);
to have your own code that runs whenever the JVM terminates under 1 of the following conditions:
The program exits normally, such as when the last non-daemon thread exits or when the Runtime.exit() method is invoked.
The virtual machine is terminated in response to a user interrupt, such as typing CTRL-C, or a system-wide event, such as user logoff or system shutdown (for example, the JVM receives one of the interrupt signals SIGHUP (Unix Only), SIGINT, or SIGTERM).
You can refer to: http://www.ibm.com/developerworks/ibm/library/i-signalhandling/ for more details (Disclaimer: very old article pertains to JDK 1.3.1)
Is there a nicer / more appropriate way for the user to inform the
application that it's time to shutdown?
The best way is to use Java Monitoring and Management
Look at this post for example.
It is best not to rely on shutdown hook.Shutdown hook in java works for KILL -15 AND KILL and do not work for KILL -9 (HARD KILL)
This is not a Java specific solution but (atleast on Linux) during shutdown, the operating system sends a SIGTERM to all processes (following by a SIGKILL after a grace period). Your application should install a handler for this and then shutdown gracefully. Once you do this, it will automatically take care of itself when you shutdown your VM.
I have a Java program that runs a number of other programs. Once the user is finished they have a button to kill all processes, this should kill everything that is running but it should do it with forcing them. At least one of these other processes is also written in Java and has a number of shutdown hooks as it automatically saves a preferences file on exit and kills processes it has started itself, such as.
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
if (process != null)
process.destroy();
}
}
When the main process calls destroy the above code is not run on the subprocess. Is there anyway that I can terminate the processes so this will still run?
I am porting from Perl which does it will the kill(9,#kill_process);
Thanks.
Kill signal 9 (SIGKILL) tells the operating system to kill the process. The process gets no notification in advance that this is going to happen and cannot do any cleanup because of it.
process.destroy() is the equivalent of Perl's kill(9,#kill_process);, and your old process wouldn't have been doing any cleanup either.
Kill signal 15 (SIGTERM) will tell a process to kill itself.
There are couple of ways how to communicate with application. One of the most common is send signal. Command for signal is called kill. Perl code you post use this aproach.
You can send various signals, some of them are handled by application some of them are handled by os.
Default signal is HUP. It tell application that "connection to user" was terminated (it actually mean modem hanged ) and it should exit. Nicely behaving application will exit.
If you send signal 9 (this is what your perl code does), OS will terminate application without question.
Another approach is to communicate with application using its default way. So you can send "Ctrl+c" or "Alt+f4" (those are commands with usually end application) to STDIN of the process.