Implement wait between processes in Java? - java

I would like some help understanding and implementing a 'wait until process complete' between the various processes in my application, which need to proceed in a step-wise fashion. My java file runs a batch file which then runs a script. At the conclusion of this there are series of commands that I need to run (through the command line) in a consecutive manner. I'm using:
Runtime.getRuntime().exec("cmd /c start " + command)
to run my batch files and commands (not sure if that information is relevant). Right now what is happening is that the second step that needs to occur in my application is executing before the first step (running the batch file which runs a script) has completed. I need the first step to conclude before running the next series of commands. I really hope I'm making sense!

exec() returns an instance of Process, on which you can do waitFor().
Watch out though: I think "start" will actually spawn off a separate Windows process, so waitFor() may return before the command has finished. Try removing "start" from the command line?

Easy:
just call the method waitFor() of your Process instance.
It will stop the thread until the external process is terminated;

Could you put that series of commands into its own batch file?
Otherwise, you could use ProcessBuilder to get a Process object, and call waitFor() on it:
causes the current thread to wait, if necessary, until the process represented by this Process object has terminated.
EDIT: Actually, exec() returns a Process, so you don't need to bother with the ProcessBuilder part at all.

Related

Java program that kills itself on new instance

So I am trying to have a Java program that starts running when the main method is invoked and stops running when the same main method is invoked (from another process). So the goal is to kill the first process with the second process, and then kill itself.
What I have tried are the following:
taskkill for Windows and kill for Unix.
This is the simplest way to do achieve the goal. But the process in Windows is always javaw.exe and calling taskkill would terminate other JVMs.
ServerSocket or DatagramSocket, to tell the first process to kill itself.
This works as well but I feel like this is just a waste for such a simple job.
File locks
The problem is that the permission of creating a file is not always granted (for whatever reason someone decides to use the program in read-only folders).
I think I might just missed something obvious. Any suggestions would be appreciated.

Is it possible to execute windows commands in Java in a "batch" manner? ie One after the other but kept persistent?

I'm looking to create a Java Application that is able to run windows commands in a "batch" manner; what I mean by this is that it's persistent in between commands and isn't as if you're only executing one at a time.
An example of this might be:
#echo off
pushd C:\foldertobepushedto\
call batchfiletobecalled.bat
popd
pushd anotherdirectorytobepushedinto
call anotherbatchfiletobecalled.bat
popd
I would like to be able to use the Process process = Runtime.getRuntime().exec(CMD); manner to be able to run each of these lines but kept persistent so that it's not as if each line is run completely separate from the rest of them.
I hope I am making a bit of sense; I intend to essentially remove the use of batch files all together and store each line as an element in a vector/array and execute them "batch" style that way.
Excuse me. I know a way to solve this problem in JScript; I ignore if there is an equivalent method for Java.
You may achieve the desired effect you want if you:
Execute CMD.EXE file alone with NO parameters, but via WshShell.Exec method:
var WshShell = new ActiveXObject("WScript.Shell");
var oExec = WshShell.Exec("cmd");
WshShell.Exec method provide access to the process standard I/O channels.
After that, send to the process' STDIN channel the commands you want to execute:
oExec.Stdin.WriteLine("#echo off");
oExec.Stdin.WriteLine("pushd C:\foldertobepushedto\");
oExec.Stdin.WriteLine("call batchfiletobecalled.bat");
oExec.Stdin.WriteLine("popd");
oExec.Stdin.WriteLine("exit");
This way, all commands will be executed in a way entirely equivalent as if they would be included in a Batch file. The only difference is that certain commands will not be correctly executed, like GOTO.

how to run shell script asynchronously from within Java program

I want to run a shell script from within a Java program asynchronously-- i.e. after the java program starts execution of that shell script, it carries on with other operations-- and does some further work only when the shell script returns a response to it.. i.e. it does not explicitly stop and wait for the shell script's response.
Is this possible/feasible? How do I implement such functionality?
Basically i will be monitoring multiple servers using a single server that will manage all those servers-- for this it will run shell scripts on each of those servers...since there are many servers, and in java its recommended that number of threads not exceed number of cpu cores... hence I need a solution to this problem, that is not dependent on threading (because of threading limitations)...so that I can simultaneously (or near-simultaneously) fire off many such shell scripts without waiting for one of those scripts responses' (as waiting would affect processing for other shell script commands)... another issue.. the shell commands need to be invoked either on local machine or on remote machines and response is needed from both types of shell script execution(viz local execution and remote execution)...
did you try anything?
you can try something like:
ProcessBuilder builder = new ProcessBuilder("your command to launch script");
Process process = builder.start();
And it does NOT wait by default for the process to complete, so you can execute your code next.
And if you want to do some processing after the process is finished you can try:
int exitVal = process.waitFor();
When you execute another process and want to obtain a result from it, you usually have to read the output of that process, as the process might block if its output buffer becomes full. The easiest way to achieve this is by having a single thread in your Java application which starts the script and then reads its output into some buffer. Other threads of the Java application can do whatever they want to do, and if the process is done, the thread can signal others about that event and then terminate.
I don't know where your recommendation to not use more threads than CPUs originates from, but I'd not hold with that in general. This is true for worker threads, where each active thread keeps one core busy, but in your case, most threads would be idle most of the time. There is some OS level resource overhead associated even with idle threads, so if there are really really many processes, using a single thread to read from all the streams would be better, but a lot more complicated.
You can use Runtime.exec or ProcessBuilder in a different thread than your application main thread to run your shell script asynchronously.
This post shows how to use Runtime or ProcessBuilder. Read this post to learn java threads if you are not aware of it.

java Process stop entire process tree

I am using Java Runtime to run commands, including certain CVS commands.
I use:
process = runtime.exec ("cmd /C cvs...");
format for running the Process in Java
I need to have the option of stopping it. For this I use the Java Process destroy method
process.destroy();
However only the cmd is stopped not the cvs process. It continues to run as a separate process without the cmd process as the parent. There are many references to this on the internet, but I haven't found any satisfactory solution. Thanks
This is a problem with the windows cmd shell. Why do you use it? Can't you do exec("cvs ...") instead?
It may be possible using Runtime.exec to get the PID of the process you have run. And with that you might be able to shut down the process tree.
You would however need 2 other programs to find the PID and to terminate the process tree.

Terminate child processes spawned by a ProcessBuilder on *nix

I'm executing a shell pipeline from a java program - it'll be something like
ProcessBuilder builder = new ProcessBuilder(
"sh", "-c", "program1 | program2 | program3");
builder.start();
In some cases this unit might need to be terminated. However
process.destroy();
Will only destroy the "sh" command. The commands in the pipline will be orphaned and adopted by the init process.
Is there any way to easily terminate all these child processes - or execute a pipeline like the above in a way that makes it easier to terminate them . Altering progam 1/2/3 can't be done. Portability beyond linux is not a issue.
There's two ways I can think to do this:
You could run a pkill program1 program2 program3
You could write a intermediate program which launches the whole bash command line, this intermediate program would install a signal handler which kills it's own children when it gets a STOP signal.
Instead of running the pipeline in the shell, build the pipeline in java.
You'll need three process builders then (one for program1, one for program2, and ... one for program3 :D), and some threads to transfer the output from each process' output stream to the input stream of the next process.
This way you get j.l.Process instances for each of the childs, and can call destroy() on those.
Create a wrapper program in C that (a) launches the rest of the pipe, and (b) handles some signals by killing all the participants in the pipe before calling exit(2) itself.

Categories

Resources