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.
Related
I have a Java program which starts another process with ProcessBuilder like the following:
String commands[] = {"ruby", "/home/scripts/script.rb"};
ProcessBuilder builder = new ProcessBuilder(commands);
Map<String,String> map = builder.environment();
map.put("TYPE", "sometype");
try {
builder.start();
} catch (IOException e) {
e.printStackTrace();
}
Some time after the process starts executing (a small Ruby Script which should not terminate) the Java program exits.
The problem is, once the Java program finishes executing, all sub-processes are closed, also the Ruby Script.
I found some similar questions but the answer was always, the Process is independent. But it is not like that in my case, the Ruby code will always stop executing if the Java program exits.
I tried the Java code on a Debian Jessie System with Java 8u66
The problem is, once the Java program finishes executing, all sub-processes are closed, also the Ruby Script.
On *nix systems (POSIX really, including Debian Linux) the process is sent a HUP signal (SIGHUP or hangup) when its' parent process ends. You can use the nohup(1) command when you start a subprocess to ignore the hangup from the child process.
Alternatively, you could potentially make use of the Ruby Signal Module and use Signal.trap(HUP) to handle it some other way.
Try to use Process.getOutputStream, wait for output from the process with runs Ruby, and if it takes too much time, then you can run in the background also.
I am writing a multithreaded Java program, which I will run from the command prompt. It's got both a gui (javafx) and a lot of background threads. If I hit Ctrl+C from the command prompt that I started the program with, it asks "Terminate Batch job? Y/N" and I hit Y and then I'm simply returned to the prompt. However - I am wondering if there by any chance might still be running any background threads that weren't terminated gracefully?
Your "main" code and all the threads run in JVM. If you terminate JVM (as process) then everything running in it will be terminated as well.
More on "catching" ctrl+c: Catching Ctrl+C in Java
As far as I know, there's no way to "catch" or "intercept" Ctrl+C "event" from the command line, so your can't really tell if there are any unfinished threads and end them gracefully. (disappointing, I know).
I am trying to write a chatbot. I am still in my startings, but I do have one question.
Process proc = Runtime.getRuntime().exec("notepad.exe");
This actually makes it impossible to quit my program, unless I quit the notepad. Is it possible to quit the Java program before this notepad has ended?
You can run an external program via a separate thread in your program and continue your program logic in your main thread, i.e. a multi-threaded application is a good solution.
First destroy the subprocess :
Process proc = Runtime.getRuntime().exec("notepad.exe");
proc.destroy();
If this doesn't work, get the process id of the process and run a different subprocess to run kill <pid>
then exit java with System.exit(0); or normally.
Blockquote
I have a Java program with functionality that needs to be run periodically. However, I would like to be able to close the wrapper program (if you're a UNIX person, think Ctrl+C in the terminal window or SIGTERM) without any risk of interrupting the main program processes or threads that the wrapper would start.
At first I was thinking I should have my main program sleep for a certain interval after each round of processing. Then I figured that if the program needs to be closed and is manually interrupted by the user, it might be interrupted while it was processing data and the output files would be chopped or corrupted.
I'm thinking the best way is to write a wrapper program (probably also in Java) that would invoke the main program. If something closes the wrapper, I would like the spawned threads or program instances of my main program to remain open until they are ready to close properly. In addition, at most one instance of the main program should be running at any time.
Here's what I would like my wrapper to do (in pseudocode):
Every n minutes:
If an instance of the main program is running, do nothing
else spawn an instance of the main program.
On Close:
leave main program run to completion if it is running
Should I use the Java Runtime object/library to run my main program (effectively from the command line) or should I change my main program to implement Runnable and have the wrapper program spawn threads running my main program?
EDIT (possible solution?):
Currently I'm thinking of using the Java Runtime object to invoke the main program using the exec function (see http://docs.oracle.com/javase/7/docs/api/java/lang/Process.html and http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html). To determine if the main program is already running I can just use the Process.exitValue() function. If it throws an IllegalThreadStateException then the main program is still running.
You can use a shutdown hook to perform an orderly shutdown when your application gets a SIGINT (Control-C): see Runtime.addShutdownHook(...).
However this doesn't deal with SIGKILL, JVM crashes, operating system crashes and hard power failures. Indeed, there is no way that an application can shut down cleanly in that kind of scenario. For that you need to design your application to periodically persist its state, using a robust persistence mechanism.
Create a new thread that has certain flags set in a static way. this thread will be run at the start of the main application, could be run/loaded from it.
Create a java event listener on the closing action of the program and regster your new thread in it. Whenever your program is closed this new thread will initiate other threads to come alive and do the final savings of the resources to perform one of the stated conditions above. your new process now will kill these threads one after another(whenever each on has done is job) until all the above conditions (flags) are met. when there is no other thread left, this new thread will kill itself, and the program is finished.
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.