Basically, I have a problem which is, I am using ProcessBuilder () to run Noxim simulator from java IDE, but neither the shell opened nor the results returned. It just displayed this error :
Exit with error code: 127
I tried the same code to execute the ping command, and it worked and returned the output shown in the shell. I also used the code run Kdeveloper and it worked well.
Note: the path is correct as It worked well in the shell
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command("/home/sa/Bureau/NOXIM/noxim/bin/noxim");
try {
Process process = processBuilder.start();
int exitCode = process.waitFor();
System.out.println("\nExited with error code : " + exitCode);
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
It's important to read the error stream too. I guess you see some more messages. Have a look here: https://gist.github.com/th-schwarz/041e13ede396a869c7681b5ad637460c
The easiest way is to read the error stream too is:
processBuilder.redirectErrorStream(true);
Related
I'm trying to run ffmpeg in Java using ProcessBuilder. I'm on Windows. It works fine. But not sure why it's much slower than when I just run the same command in command prompt or PowerShell.
Why is it? Is there any ways to increase the speed?
processBuilder.command("C:\\Windows\\System32\\cmd.exe", "/c","ffmpeg.exe", "-y", "-i", video,"-vf","scale=720:-1","out.mp4");
processBuilder.redirectErrorStream(true);
try {
process = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line="";
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (Exception e) {
System.err.println("Error in processBuilder. ");
}
You have two starts, delete the first or the redirect will not work:
process = processBuilder.start();
If your sub-process is quite verbose the problem may simply be System.out.println() as multiple line output to some Windows cmd / terminals can be exceptionally slow. You can verify if this is the case by commenting out the print, or capture to File based output before start:
processBuilder.redirectOutput(new File("stdout.log"));
Don't forget to add status check at the end and cross check rc with ffmpeg documentation:
int rc = process.waitFor();
I am working on a project in Java where I am trying to get the size of the terminal window. I have found that stty size returns the size in rows and columns which I am fine with.
My problem is to get the values using Java. So far I have this:
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command("stty", "size");
try {
Process process = processBuilder.start();
InputStreamReader is = new InputStreamReader(process.getInputStream(), "UTF-8");
BufferedReader reader = new BufferedReader(is);
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
This outputs:
[I#6ce253f1
However, when I just run stty size on my own, I get 30 213. I assume it is some sort of encoding issue but I am not sure.
Try
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command("stty", "size");
processBuilder.redirectErrorStream(true);
processBuilder.redirectInput(ProcessBuilder.Redirect.INHERIT);
try {
...
Then you get an error message which is written to the error channel, too. And the input channel is set to the same input channel the Java process is using.
I'm playing a bit around with a small JAVA gui for the command line mode of cloudcompare.
Therefore I'm using a short snippet like these:
var processBuilder = new ProcessBuilder();
try {
var process = processBuilder
.command("open", "-a", "CloudCompare.app", "-n",
"--args", "-NO_TIMESTAMP", "-C_EXPORT_FMT", "LAS",
"-O", "/Users/se/pcl_1.las",
"-O", "/Users/se/pcl_2.las",
"-MERGE_CLOUDS")
.start();
String error, line;
BufferedReader inputStream = new BufferedReader(new InputStreamReader(process.getInputStream()));
while ((line = inputStream.readLine()) != null) {
System.out.println("line = " + line);
}
BufferedReader errorStream = new BufferedReader(new InputStreamReader(process.getErrorStream()));
while ((error = errorStream.readLine()) != null) {
System.out.println("error = " + error);
}
var ret = process.waitFor();
System.out.printf("Program exited with code: %d", ret);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
But if I run it on macOS the command line window opens, the process runs normal, but I can't grab any of the informations in it. There is an option to write log files from cloudcompare. That works - the log file shows that all cloud processing steps are done.
Does anybody knows, how to grab the command line output?
As mentioned here, the /usr/bin/open command is not an option to grab the stdinput stream.
I change the command to /Applications/CloudCompare.app/Contents/MacOS/CloudCompare and it works.
The next question is, how to grab the InputStream with a thread. I tried some stack overflow topics, but it doesn't work at the moment, to get the output stream in realtime. It is flushed at the end of the CloudCompare process.
I want the Apache Cordova CLI being called by a Java Process but unfortunatly the Java Process doesn't wait until it is finished.
This is, how i call it:
StringBuffer sb = null;
String cmd = "cd /location/generated && cordova create MyNewApp"
try {
Process p = Runtime.getRuntime().exec(cmd);
p.waitFor();
BufferedReader reader =
new BufferedReader(new InputStreamReader(p.getInputStream()));
sb = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
I've seen many solutions, that say "waitFor()" will do the trick but unfortunatly not for me. I've already tried to always read and compare the last line of code generated by the cordova cmd and finish afterwards, but this is not a good approach. Do you have any suggestions?
Resolved it:
Cmd looks like this "cordova create /path/to/generated/app/ Hello World"
Be aware, the path has to exist before the cmd is beeing called
I am running a script in a java program using:
Runtime.getRuntime().exec()
I am able to open the terminal application using this.
If I give command to run the script. It's happening but I am not able to get the logs in the terminal. I am using MAC. I want to get the logs in the terminal.
You can use a Process variable to get what return from that command, and use method such as: getInputStream(), getOutputStream(), getErrorStream(). Example:
Process p = null;
try {
p = Runtime.getRuntime().exec(....your stuff here)
p.getOutputStream().close(); // close stdin of child
InputStream processStdOutput = p.getInputStream();
Reader r = new InputStreamReader(processStdOutput);
BufferedReader br = new BufferedReader(r);
String line;
while ((line = br.readLine()) != null) {
//System.out.println(line); // the output is here
}
p.waitFor();
}
catch (InterruptedException e) {
...
}
catch (IOException e){
...
}
finally{
if (p != null)
p.destroy();
}
The Process object returned by the method call above has an getInputStream() method (as well as ones for the error and output streams). You have to read from those if you want to grap the inputs and outputs of your script.
For reference: http://docs.oracle.com/javase/7/docs/api/java/lang/Process.html
in terminal, using > to output the log to file. For example: ls / > rootfolder.txt
Using that way, you can output the log to file and then read the log from the file.