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.
Related
My Problem today is:
I need to start a Program (it's a C++ program) from Java. When the Java program stops, the C++ Program needs also to stop and vice versa.
My Ideas:
I need to run the Program in a new Thread. When the thread stops, I can exit the java program. And if the Java program stops, the thread will be killed.
or
I need to run the Program in a new Sub-Process of the Java Process. And receive in the Java Process signals to check if the child process dies.
Does anyone know how I can get this behavior?
You can add a shutdown hook in the main Thread, and in this hook you can kill the application, or send an exit signal.
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
// kill the application here!!!
killCProgram();
}
});
In the code above, the java application will wait for killCProgram.
In truth, if is two process, they are independents.
I've written a very simple command line programme that uses mysqldump to dump data at a specified interval. I wanted it to be running after I run the programme and I disconnect putty ssh connection.
But as soon as I exit the ssh connection, the programme shuts down.
I think I can make my programme run even after I disconnected from the ssh by using daemon threads but I'm worried about not being able to find and stop unnecessary duplicate daemon threads.
The scenario I'm decribing is...
1. I log into the server using putty.
2. Turn on the auto backup programme.
3. I exit the putty connection.
---the daemon is running
4. Hopefully, when I log into the server again, I have a way to stop the auto backup programme if needed.
Cron jobs and DBMS specific methods are out of my options. I'd like to learn how to do the job described above and use it where ever the situation fits not just database backup.
Any good ideas ? : )
In short, you have to launch your program in a special way, and you have (at least) two options: nohup or screen.
Let's now discuss why and how each one works.
nohup
Java's daemon threads is not what you are looking for, they have nothing to do with the issue. You can use normal threads (or even a single-threaded java program). You just need to change the way you launch your java program.
I have many executable jars that run as "daemons" on a bunch of servers, and I made a simple launch script that prepares the environment and makes it possible to terminate the SSH connection without stopping it. The main part is how to invoke the JVM: you use nohup.
nohup java -jar myfile.jar > stdout.log &
From nohup's man,
nohup - run a command immune to hangups, with output to a non-tty
So, when you terminate your SSH connection, it will send SIGHUP to all processes it started which would terminate them as you are observing. With nohup, however, your process is immune to it.
Also, note that I redirect the standard output to a file called stdout.log. This is done so that you can see whatever your program writes to STDOUT (generally some logging information that would be useful for debugging).
To terminate your program, you can use jps to list the PID of your process (say it's 123), then call kill 123. Note that for this to work your program needs to correctly handle this kind of shutdown (which involves adding a shutdown hook with Runtime.getRuntime().addShutdownHook(...) which will terminate all the threads you launched).
If, for whatever reason (a bug, or you didn't implement a graceful shutdown), the program won't terminate after issuing the kill command (which sends the process a SIGTERM), you can change the signal it sends to SIGKILL with kill -9 123, which will simply destroy the process. Mind that this can be as dangerous as a power failure (ie, suppose you are in the middle of the try block of a try {} finally {} -- your finally block will not execute!).
screen
There's an alternative, which is to use SCREEN. With it, you launch a shell that is also immune to shutdowns, and that you can share among many connections. To use it, connect to your server, and then:
screen -R
A new shell will start, in which you run your java program as normal:
java -jar myfile.jar
To make it go to the background, just press ctrl+a ctrl+d. To bring it back to the front, just execute screen -R again. If you wish to terminate your program, you could do so by entering the screen session again and pressing ctrl+c (if your java program correctly deals with this kind of shutdown).
Two possibilities for scheduled tasks, in order from least to most complex, are the TimerTask and the Quartz Scheduler. Both offer the option to cancel/delete the scheduled job.
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.
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 Swing application that is being used as a cluster application. The problem is that every time the cluster tries to terminate the Java application, it just hangs and Windows displays the "End Now" dialog. The said application is a server type one so it spawns a thread for every attempt to connect to it is made.
I learned that the cluster sends the TERM signal using the program presented in this article. BUT when the console application is used as a cluster application, the cluster can just terminate the process after a few TERM signals.
I also tried the vanilla sample desktop application that's available when making a new project using NetBeans 6.8. It also won't terminate even after receiving the signal.
From the demonstrations done above, I think that it has something to do with Swing or with the threads. Can anyone help me with this? Thank you.
EDIT: It could be killed by using the task manager though I think it sends another signal.
When your Java application receives the TERM signal it will run any registered shut-down hooks before terminating. One possibility is that one of these shut-down hooks is blocking indefinitely or else taking a long time (>30 seconds) to run, causing the Windows "End Now" dialog to be displayed.
One thing you could try is to register a shut-down hook that simply prints to the console and verify that it is indeed being called. However, unfortunately there'll be no way to determine whether other shut-down hooks have run at this point as hooks are run in an arbitrary order.