how to increase the performance of cmd command in window - java

I am using java to call arp -s command and waiting for the process to finish in order to complete function .
String command ="arp -s "+entryIpAddress+" ee-ee-ee-ee-ee-ee-ee";
Process p=Runtime.getRuntime().exec(command);
p.waitFor();
but the calling of this process is taking more than the usual time so, is there a way to increase the performance of this method. i cannot remove the p.waitFor() my next function depend on the added entry.

Your code doesn't show any sign of effort towards allowing the process to complete ever. You are not consuming its output, so its output buffer will soon fill up, blocking further progress.
To make this task easier on yourself, please use the ProcessBuilder.

Related

ProcessBuilder: process doesn't finish without "redirectOutput"

I'm automating a gradle build using Java. I execute "gradlew.bat" in a Process created from a ProcessBuilder. Here's the code:
ProcessBuilder gradlewProcessBuilder = new ProcessBuilder(mainDirPath.concat("\\android\\gradlew.bat"), "assembleDebug");
gradlewProcessBuilder.directory(new File(mainDirPath.concat("/android")));
gradlewProcessBuilder.redirectOutput(ProcessBuilder.Redirect.INHERIT); //This is the line
Process gradlewProcess = gradlewProcessBuilder.start();
gradlewProcess.waitFor();
Now this code works flawlessly, but it outputs the gradle console through the application console and I don't want that. If I delete this line:
gradlewProcessBuilder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
The process hangs in waitFor() indefinitely.
I have absolutely no idea how could redirectOutput have effect over this, any light you can shed is welcome.
If the output is not redirected or handled, then a default output buffer is allocated. However, on Windows the output buffer is very small; when it fills up, the app will stop executing and will block until the output buffer is drained.
Therefore, you need to drain the output somehow; either by using INHERIT or by having a thread which drains the output. I recommend using https://github.com/zeroturnaround/zt-exec since it has much better default handling.

Process hanging on the process builder

I am working on java process builder to execute the windows external process(i.e., exe files). I have to get the process info and error using input stream, error stream to write it in some text files.
It's working sometimes and unexpectedly hanging sometimes.
When i invoke around three external process to execute one by one. Two process working and it's getting hang on third process only.
I could see the process exit value as 0 some times it's giving some other random value.
I have read the below blog and applied the same logic to execute the process but's not working for my scenarios.
Could anybody please help me to diagnose these problem...
//Starts to initiate the external process
//This code will pick three arguments from to execute the process sequentially
//it will pass the process commands through for loop one by one
Process p =new ProcessBuilder(s)
.directory(new File(je.getExecution().getWorkingDirectory()))
.redirectErrorStream(true)
.redirectOutput(file)
.start();
p.getOutputStream().close();
int processStatus= p.waitFor();
// if the process exits with 0 normal termination
Thanks in advance..,
The entire thing you are doing is error prone and it’s not worth trying to find out all of the mistakes, as you are making your life unnecessarily hard.
Note that you are calling redirectErrorStream(true), but still are trying to read from the error stream, which makes no sense. The error stream will always be empty under this condition. That said, if you already know about redirections, it’s not clear, why you don’t use them directly, instead of creating threads, manually copying data into StringWriters, etc.
Apparently, you want to use the working directory je.getExecution().getWorkingDirectory(), launch the command s and directing both, output and error, of the program to file. This can be achieved as easy as
new ProcessBuilder(s)
.directory(je.getExecution().getWorkingDirectory())
.redirectErrorStream(true).redirectOutput(file)
.start()
.waitFor();
The only remaining error source is that the launched process could wait for input from your side. Since you apparently don’t want to provide input, you can use
Process proc = new ProcessBuilder(s)
.directory(je.getExecution().getWorkingDirectory())
.redirectErrorStream(true).redirectOutput(file)
.start();
proc.getOutputStream().close();
proc.waitFor();
to denote that you won’t write any data. This will not stop the process, but when it tries to read something from its standard input, it will immediately get an end-of-file without blocking.
Which can be demonstrated with
Process proc = new ProcessBuilder("cmd", "/c", "pause")
.redirectErrorStream(true).redirectOutput(file)
.start();
proc.getOutputStream().close();
proc.waitFor();

Executing Unix Script through plink from JAVA Runtime

I am using below code to trigger script of Unix through Java.I am not able to figure out why this command is not working.
String cmd="E:\\plink.exe -ssh -l user -pw p123 10.xxx.xx.xx \"sh /home/try.sh\"";
System.out.println(cmd);
Process process=Runtime.getRuntime().exec(cmd) ;
process.destroy();
Do i need to make some correction in it?
Runtime.exec only starts the specified program/process. You immediately destroy it before it has time to connect and send the commmand, as you want it to. At a minimum you should .waitFor() it to complete.
You don't say if the script produces (any) output. If it does and you want anything to happen with that output, like being displayed or saved someplace, you need to read from Process.getInputStream() and do your thing. Also if your script needs input (less common) you need to write it to .getOutputStream().

Java process.waitFor() does not return

On Windows 7 64 bit, running 64 bit Java 1.7.0_17 , the p.waitFor() shown below never returns.
String move_command="cmd.exe /c xcopy /Y /E "+x86_release+" "+path+"\\";
Process p;
p = Runtime.getRuntime().exec(move_command);
p.waitFor();
If I use Windows Explorer, it looks like all the files are copied (same number, same size, etc.)
If I do the below, it waitFor() does return:
String move_command="cmd.exe /c move /Y "+x86_release+" "+path+"\\";
Process p;
p = Runtime.getRuntime().exec(move_command);
p.waitFor();
What could be so different between an xcopy and a move that keeps waitFor() from returning, or am I on the wrong track entirely?
xcopy probably just happens to produce more output than move, filling up the out-buffer and blocking until it is flushed. The default behavior in Java is to pipe the subprocess's stdout/stderr into InputStreams that you are then required to read programmatically lest the subprocess's buffers overflow.
If the latter is the case, the solution is simple, and in fact you should do that anyway: use ProcessBuilder to prepare the system call and call inheritIO on it. This will reuse your parent process`s stdin and stdout for the subprocess.
A side note, xcopy is a regular .exe file and doesn't need wrapping into cmd.exe /c.
I suspect you're not consuming the process standard out/err, and that's blocking the process. If your code doesn't consume this output, then the spawned process will hang (and you'll hang waiting for that process!). Why the difference in behaviour between the two commands ? Probably due to the quantity of data returned and the impact on the publishing buffers.
See this answer for more details.
I would also investigate Apache Commons FileUtils.copyDirectory() such that you don't have to spawn a whole new process to copy files.

The best way to monitor output of process along with its execution

I have started a process in my Java code, this process take a very long time to run and could generate some output from time to time. I need to react to every output when they are generated, what is the best way to do this?
What kind of reaction are you talking about? Is the process writing to its standard output and/or standard error? If so, I suspect Process.getInputStream and Process.getErrorStream are what you're looking for. Read from both of those and react accordingly. Note that you may want to read from both of them from different threads, to avoid the individual buffer for either stream from filling up.
Alternatively, if you don't need the two separately, just leave redirectErrorStream in ProcessBuilder as false, so the error and output streams are merged.
You should start a thread which reads from the Process.getInputStream() and getErrorStream() (or alternatively use ProcessBuilder.redirectErrorStream(true)) and handle it when something shows up in the stream. There are many ways that how to handle it - the right way depends on how the data is being used. Please tell more details.
Here is one real-life example: SbtRunner uses ProcessRunner to send commands to a command line application and wait for the command to finish execution (the application will print "> " when a command finishes execution). There is some indirection happening to make it easier to read from the process' output (the output is written to a MulticastPipe from where it is then read by an OutputReader).

Categories