I call a class which is located somewhere in a jar file (using java -classpath path/file.jar classname) within my java code.
This work well but only if the command is well formed. If I make a mistake the getRuntime().exect(command) just doesn't say anything. Bellow I have the working command invocation. I would like to get the error message when the command doesn't work. If I make a mistake in a cmd (windows) I get a proper error and I can fix it. But not within my java application.
I left a 'if(input.ready())' since if I don't the program freezes when the command line is incorrect. This happens when executing 'input.readLine()'.
// Execute a command with an argument that contains a space
String[] genKOSCommand = new String[] {
"java",
"-classpath",
Config.XDSI_TEST_KIT_HOME + "/xdsitest/lib/xdsitest.jar;"
+ Config.XDSI_TEST_KIT_HOME + "/xdsitest/classes",
"ca.etsmtl.ihe.xdsitest.docsource.SimplePublisher", "-k",
"C:/Softmedical/Viewer_Test/xdsi-testkit-2.0.4/xdsihome/usr/data/image14.dcm" };
Process child = Runtime.getRuntime().exec(genKOSCommand);
BufferedReader input = new BufferedReader(new InputStreamReader(
child.getInputStream()), 13107200);
String line = null;
if (input.ready()) {
while ((line = input.readLine()) != null) {
System.out.println(line);
}
try {
child.waitFor();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Have any advice on how to get an error from the executed command?
Thank you
By using getErrorStream:
BufferedReader errinput = new BufferedReader(new InputStreamReader(
child.getErrorStream()));
When processing the input from the different streams, it is better to do it in a different thread (since those calls (readLine etc.) are blocking calls.
Here's a bit more complete piece of code to print out errors received upon running some command via Process/Runtime:
final String command = "/bin/bash -c cat foo.txt | some.app";
Process p;
try {
p = Runtime.getRuntime().exec(command);
} catch (final IOException e) {
e.printStackTrace();
}
//Wait to get exit value
try {
p.waitFor();
final int exitValue = p.waitFor();
if (exitValue == 0)
System.out.println("Successfully executed the command: " + command);
else {
System.out.println("Failed to execute the following command: " + command + " due to the following error(s):");
try (final BufferedReader b = new BufferedReader(new InputStreamReader(p.getErrorStream()))) {
String line;
if ((line = b.readLine()) != null)
System.out.println(line);
} catch (final IOException e) {
e.printStackTrace();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
Isn't Process.getErrorStream what you want?
Related
I need to run a shell script in java. The script accepts two parameters as an argument 1st is the name and the second is the directory path.
I'm using Windows as the operating system on my local machine.
Below is the code I'm trying to run:
ProcessBuilder processBuilder = new ProcessBuilder("D:\\temp\\script\\create_script.sh", name, sourceDir);
try {
Process process = processBuilder.start();
StringBuilder output = new StringBuilder();
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
output.append(line + "\n");
}
int exitVal = process.waitFor();
if (exitVal == 0) {
System.out.println("Success!");
System.out.println(output);
System.exit(0);
} else {
//abnormal...
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
The above code gives below error:
2021-05-12 22:08:47.383 INFO 10600 --- [nio-8090-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms
java.io.IOException: Cannot run program "D:\temp\script\create_script.sh": CreateProcess error=193, %1 is not a valid Win32 application
at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1128)
at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1071)
Can someone please help me with the missing part?
Appreciate all your help! Thanks in advance!
If you are using Windows, the problem might be that you are trying to run a Linux shell script (.sh), hence Windows doesn't really appreciate that.
You can either translate Linux shell script into Windows bash script or try to run your program again on a Linux OS, which I would recommend the latter.
The below code worked for me!
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command("cmd.exe", "/c", "D:\\temp\\script\\create_script.sh);
try {
Process process = processBuilder.start();
StringBuilder output = new StringBuilder();
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
output.append(line + "\n");
}
int exitVal = process.waitFor();
if (exitVal == 0) {
System.out.println("Success!");
System.out.println(output);
System.exit(0);
} else {
//abnormal...
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
I have code that runs batch files in windows perfectly fine. (hey.bat just prints something simple)
public static void main(String[] args) {
static String dir1 = "C:\\Users\\Name\\Desktop\\hey.bat";
ProcessBuilder processBuilder = new ProcessBuilder(dir1);
try {
Process process = processBuilder.start();
StringBuilder output = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
output.append(line + "\n");
}
int exitVal = process.waitFor();
if (exitVal == 0) {
System.out.println(output);
System.exit(0);
} else {
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
However, when I call a different batch file named shutdown.bat, one that is supposed to shutdown Tomcat, it gives the error
The CATALINA_HOME environment variable is not defined correctly. This
environment variable is needed to run this program
When I double click shutdown.bat it works perfectly fine, so why would it give an error when being run through java? Shouldn't all the dependencies be bundled into that batch file? Thanks
I use a standard Java routine to execute a terminal command, however I haven't been able to get it to work to run a python file including arguments.
The terminal command (which works on the terminal) is:
python3 umlsConverter.py colon cancer
Where colon cancer is one of N possible string arguments
The Java routine I usually run (from Eclipse) to execute terminal commands is:
public static String execCmdV2(String cmd,String workingDirectoryPath) {
Runtime rt = Runtime.getRuntime();
//String[] commands = {"system.exe","-get t"};
String[] env= {};
Process proc;
File runDir = new File(workingDirectoryPath);
try {
proc = rt.exec(cmd,env,runDir);
} catch (IOException e1) {
System.out.println("Error executing command:" + e1.getLocalizedMessage());
return null;
}
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(proc.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(proc.getErrorStream()));
// read the output from the command
System.out.println("Here is the standard output of the command:\n");
String fullOutputstring = null;
String s = null;
try {
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
fullOutputstring = fullOutputstring + s;
}
} catch (IOException e) {
System.out.println("Unable to output the results due to error:" + e.getLocalizedMessage());
return null;
}
// read any errors from the attempted command
System.out.println("Here is the standard error of the command (if any):\n");
try {
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
} catch (IOException e) {
System.out.println("Unable to output the errors due to error:" + e.getLocalizedMessage());
return null;
}
return fullOutputstring;
}
And the error I get, when I run the routine for:
cmd = "python3 umlsConverter.py Breast cancer"
and
`workingDirectoryPath="/Users/n9569065/QuickUMLS"`
is
Error executing command:Cannot run program "python3" (in directory "/Users/n9569065/QuickUMLS"): error=2, No such file or directory
I think the problem has something to do with accessing python3?
use the full path of the python executable. for example: /usr/bin/python3
i am running jdk on windows 7. I try to run a external software (pocketsphinx_continous.exe) within my java application. The software runs permanently (pocketsphinx_continous.exe) and prints some output to the console which i like to read by my java application.
if i run "pocketsphinx_continous.exe" with some params from the commandline all works well and i see the output from the software. After killing the process, i try to run it within my java application. But java print no output to the console.
This is my code:
public void start(){
try {
Runtime rt = Runtime.getRuntime();
String[] commands = {"D:/cmusphinx/pocketsphinx/bin/Release/x64/pocketsphinx_continuous.exe", "-hmm", "d:/cmusphinx/pocketsphinx/model/en-us/en-us", "-lm", "d:/cmusphinx/pocketsphinx/model/en-us/en-us.lm.bin", "-dict", "d:/cmusphinx/pocketsphinx/model/en-us/cmudict-en-us.dict", "-samprate", "16000/8000/48000", "-inmic", "yes"};
Process proc = rt.exec(commands);
BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
// read the output from the command
System.out.println("Here is the standard output of the command:\n");
String s = null;
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
// read any errors from the attempted command
System.out.println("Here is the standard error of the command (if any):\n");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Java will only print "Here is the standard output of the command:" and nothing more. But it wont crash, its still running without any errors. It seems to me java will wait until the executed command is finished until it prints anything. But the software will run permanently and print some times new results ...
Any ideas?
Best regards
Mike
I suggest you do the following:
Process p = null;
ProcessBuilder b = new ProcessBuilder("D:/cmusphinx/pocketsphinx/bin/Release/x64/pocketsphinx_continuous.exe -hmm d:/cmusphinx/pocketsphinx/model/en-us/en-us -lm d:/cmusphinx/pocketsphinx/model/en-us/en-us.lm.bin -dict d:/cmusphinx/pocketsphinx/model/en-us/cmudict-en-us.dict -samprate 16000/8000/48000 -inmic yes");
try {
p = b.start();
} catch (IOException e) {
e.printStackTrace();
}
BufferedReader output = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
try {
while ( (line = output.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
Using ProcessBuilder you don't have to separate parameters. Just copy the whole command in a String.
I am trying to run the below command from java and want to capture the output. The method is getting completed immediately without writing anything to the console.
Linux Command is repo forall -c 'echo pwd is;pwd;git status'
and the method is
public static String executeCommandWithOutput(String command) {
System.out.println("Running the command "+command);
StringBuffer output = new StringBuffer();
String line = "";
try {
Process process =Runtime.getRuntime().exec(command);
process.waitFor();
BufferedReader reader =
new BufferedReader(new InputStreamReader(process.getInputStream()));
while ((line = reader.readLine())!= null) {
output.append(line);
}
System.out.println("Content is "+output.toString());
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return output.toString();
}
I tried redirecting the output to a file as well. Neither worked. Any thoughts??
Check if the command your are trying to execute has a standard output.
Probably its failing and you are getting error output.
You can check the error output with getErrorStream, documentation is here.
E.g. like this
StringBuffer error = new StringBuffer();
BufferedReader reader =
new BufferedReader(new InputStreamReader(process.getErrorStream()));
while ((line = reader.readLine())!= null) {
error.append(line);
}
System.out.println("Error is " + error.toString());
Also check the exitValue of your forked command, doc is here
int exitStatus = process.exitValue();
System.out.println("Exit status is " + exitStatus );