On Windows, I try to execute a java command (java -version for example) using Runtime.getRuntime().exec("java -version").
There is no errors , but the command seems to be never executed. Or JAVA is called but do nothing.
I put this command in a BAT file and try to execute Runtime.getRuntime().exec("file.bat").
I have the same bad result.
Six months before, it was OK.
Is there any RESTRICTIONS now to do that ? Only on Windows ?
Thanks for your help.
Try to send -version as a second String to the Runtime Executor.
Additionally, you can log the OutputStream to help investigate the issue.
try {
Process process = Runtime.getRuntime().exec(new String[]{"java", "-version"});
try (BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
String line;
while((line = br.readLine()) != null){
LOGGER.info("RuntimeProcess Printed: {}", line);
}
}
} catch (IOException e) {
LOGGER.error("ERROR: {}", e);
}
Lastly, be mindful of the command you are running. For instance if you try to run a Unix command on a Windows machine you're going to see exceptions.
Hope this helps.
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();
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);
I'm trying to run a multi-agent system using JADE by code.
Usually, I can run the jade system by command line using the following command:
java jade.Boot -gui
It also works well using Netbeans IDE by changing the project properties and pointing the run configuration to the jade.Boot class.
My problem is: I want to run this system by java code... let's say, when a user clicks a button, and as far as I know, this command specified above should work using the following code:
Process p=null;
try {
p = Runtime.getRuntime().exec("java jade.Boot -gui;");
}
catch (IOException ex) {
Logger.getLogger(SimulationCreator.class.getName()).log(Level.SEVERE, null, ex);
}
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
String s;
try {
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
} catch (IOException ex) {
Logger.getLogger(SimulationCreator.class.getName()).log(Level.SEVERE, null, ex);
}
But I'm getting nothing, neither the JADE system is running nor I'm getting any error.
What am I missing ?
P.S.: I'm working on ubuntu 20.0.
P.S.: running other commands by code like "ps -aux" works very well!
Your problem may be a difference between PATH of the current running VM, compared the shell (bash etc) you use and implicit passing of CLASSPATH. Check the location of java which which java in the shell that works and try using in your exec.
Also you won't see all issues when running as you don't access the error stream at same time as the output stream, changing to ProcessBuilder allows easier debugging as you can redirect the out/err streams to a file. But if JADE runs for a long time or produces a lot of output you should consumer STDOUT+ERR in background threads.
Try this in jshell:
String[] cmd = new String[]{"java", "jade.Boot", "-gui"};
ProcessBuilder pb = new ProcessBuilder(cmd);
File fileOut = new File("stdout.log");
File fileErr = new File("stderr.log");
pb.redirectError(fileErr);
pb.redirectOutput(fileOut);
Process p = pb.start();
int rc = p.waitFor();
String stdout = Files.readString(fileOut.toPath());
String stderr = Files.readString(fileErr.toPath());
System.out.println("Exit : "+rc +' '+(rc == 0 ? "OK":"**** ERROR ****"));
System.out.println("STDOUT : "+stdout);
System.out.println("STDERR : "+stderr);
I am trying to build a GUI for GCC which has some basic functionalities like compile, link, execute, debug, etc for C++ programs using Java. I am creating strings of command which I pass to the ProcessBuilder and run it via command prompt and GCC.
command = "cd src & cd Resources & g++ " + compileFile.cpp +" -Wall "+ " -o "+ "tempOut";
This is a sample code for compiling the file.
Part of this is the debug functionality for which I am using GDB. Now the problem is GDB needs additional input to add breakpoints, remove breakpoints and so on. I am having trouble on how to pass these necessary inputs to GDB via Java terminal. If I pass the commands in the command prompt, it is working fine and I get the desired output.
enter image description here
But whenever I fire the GDB command from the Java program, I cannot pass any inputs from the IDE's terminal. I am aware that each GDB command uses a different process and I tried attaching Java's process ID to GDB but I just get a blank output console. It seems that the GDB session has started but there is no way to interact with that process through the IDE's output console.
int pid = Integer.parseInt(ManagementFactory.getRuntimeMXBean().getName().split("#")[0]);
command = "gdb attach "+ pid;
fireCommand();
EDIT
This is the method that interacts with command prompt to take input and display output in the IDE's output console:
public void fireCommand() {
String line;
String os = System.getProperty("os.name");
ProcessBuilder builder;
if(os.startsWith("Win")) {
builder = new ProcessBuilder("cmd.exe", "/c", command);
}
else{
builder = new ProcessBuilder("bash", "-c", command);
}
try {
process = builder.start();
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
while ((line = reader.readLine()) != null) {
if(line.contains("Input the value")) {
//any other user input in non debug execution
String value = JOptionPane.showInputDialog(line);
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(process.getOutputStream()));
writer.write(value, 0, value.length());
writer.newLine();
writer.close();
}
else {
output.append(line).append("\n");
}
}
int exitVal = process.waitFor();
if (exitVal == 0) {
//display("Success!");
display(output.toString());
} else {
String lineErr;
BufferedReader readerErr = new BufferedReader(
new InputStreamReader(process.getErrorStream()));
while ((lineErr = readerErr.readLine()) != null) {
outputErr.append(lineErr).append("\n");
}
//display(exitVal);
display(outputErr.toString()); //Display the uncatched errors
}
} catch (IOException e) {
display("There was a problem with the I/O");
e.printStackTrace();
} catch (InterruptedException e) {
display("There was a interruption with the execution");
e.printStackTrace();
}
if(!outputErr.toString().isEmpty())
errorFormatDisplay(); //display Error output function
}
Any leads on this would be very helpful. Thank you.
I am aware that each GDB command uses a different process
No, gdb runs as one process. Did you mean to say that you are creating a new gdb process every time you try to pass it a gdb command ?
It seems that the GDB session has started but there is no way to interact with that process through the IDE's output console.
Maybe you should use The GDB/MI Interface, which e.g. the Emacs debugger mode gud uses.
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.