java: parse output of execute command - java

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.

Related

Null output from Runtime.getRuntime.exec() in java

I am trying to execute a series of JDEPS commands using a loop in java. I have used Process object to capture the execution of the command([Runtime.getRuntime.exec("command")][1]), and using [BufferedReader][2] to take the process input and error streams. But the output is coming as null. There are no error codes as well. I have run the command manually on the terminal and it work fine.
Can anybody suggest anyway of how to figure out what is the issue, or as to why this null output is coming?
Please find my code for executing the command below:
private String[] runCommandByType(String command,int type)
{
String s=null;
ArrayList<String> output = new ArrayList<String>();
try {
// using the Runtime exec method:
Process p = Runtime.getRuntime().exec(command);
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
// read the output from the command
while ((s = stdInput.readLine()) != null) {
if(type==0) //takes in all the output
{
output.add(s);
}
if(type==1) //takes only the dependent class names
{
s=s.substring(0, s.indexOf("->")).replaceAll("\\s+","");
output.add(s);
}
}
// read any errors from the attempted command
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
}
catch (IOException e) {
System.out.println("$$$$ Exception happened $$$$");
e.printStackTrace();
}
return output.toArray(new String[output.size()]);
}
Thanks in advance!

How to run a Python3 file from Java on the mac

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

Getting output from executing a terminal command in a java code running inside Cubieboard Platform

The code that I am using for running a terminal command in Linux Debian and getting the output inside a java program is this:
public static String execute(String command) {
StringBuilder sb = new StringBuilder();
String[] commands = new String[]{"/bin/sh", "-c", command};
try {
Process proc = new ProcessBuilder(commands).start();
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(proc.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(proc.getErrorStream()));
String s = null;
while ((s = stdInput.readLine()) != null) {
sb.append(s);
sb.append("\n");
}
while ((s = stdError.readLine()) != null) {
sb.append(s);
sb.append("\n");
}
} catch (IOException e) {
return e.getMessage();
}
return sb.toString();
}
Now the problem is, it works for normal commands like ls / and gives back the appropriate result. But my goal is to run commands like:
echo 23 > /sys/class/gpio/export
which is, for example, for activating the gpio pin in the CubieBoard platform.
(Cubieboard is a mini-pc board like Raspberry Pi).
Now running this command in the terminal of the system itself, works fine and gives me the proper result. But when i am running it from this java code, i cannot get any results back.
The point is that, it works and the command executes well, but just that i cannot get the output message of the command!
For example if the pin was active from the past, then normally it should give me back the result like:
bash: echo: write error: Device or resource busy
But when i run this command through java code above, i do not get any response back.
(again it takes effect but just the response of the terminal i cannot get!)
When i run the code, both stdInput and stdError variables in the code are having the value null. :(
Please help me so that i can finish my project. this is the only part that is remaining :(
Thank you.
There maybe the childProcess doesn't run to end
Please to try:
proc.waitFor()
and run read stdInput and stdError in other Thread before proc.waitFor().
Example:
public static String execute(String command) {
String[] commands = new String[] { "/bin/sh", "-c", command };
ExecutorService executor = Executors.newCachedThreadPool();
try {
ProcessBuilder builder = new ProcessBuilder(commands);
/*-
Process proc = builder.start();
CollectOutput collectStdOut = new CollectOutput(
proc.getInputStream());
executor.execute(collectStdOut);
CollectOutput collectStdErr = new CollectOutput(
proc.getErrorStream());
executor.execute(collectStdErr);
// */
// /*-
// merges standard error and standard output
builder.redirectErrorStream();
Process proc = builder.start();
CollectOutput out = new CollectOutput(proc.getInputStream());
executor.execute(out);
// */
// child proc exit code
int waitFor = proc.waitFor();
return out.get();
} catch (IOException e) {
return e.getMessage();
} catch (InterruptedException e) {
// proc maybe interrupted
e.printStackTrace();
}
return null;
}
public static class CollectOutput implements Runnable {
private final StringBuffer buffer = new StringBuffer();
private final InputStream inputStream;
public CollectOutput(InputStream inputStream) {
super();
this.inputStream = inputStream;
}
/*
* (non-Javadoc)
*
* #see java.lang.Runnable#run()
*/
#Override
public void run() {
BufferedReader reader = null;
String line;
try {
reader = new BufferedReader(new InputStreamReader(inputStream));
while ((line = reader.readLine()) != null) {
buffer.append(line).append('\n');
}
} catch (Exception e) {
System.err.println(e);
} finally {
try {
reader.close();
} catch (IOException e) {
}
}
}
public String get() {
return buffer.toString();
}
}
the code is right, just in the second line, I changed
"/bin/sh" to "/bin/bash"
And everything works!
sh == bash?
For a long time, /bin/sh used to point to /bin/bash on most GNU/Linux systems. As a result, it had almost become safe to ignore the difference between the two. But that started to change recently.
Some popular examples of systems where /bin/sh does not point to /bin/bash (and on some of which /bin/bash may not even exist) are:
Modern Debian and Ubuntu systems, which symlink sh to dash by default;
Busybox, which is usually run during the Linux system boot time as part of initramfs. It uses the ash shell implementation.
BSDs. OpenBSD uses pdksh, a descendant of the Korn shell. FreeBSD's sh is a descendant of the original UNIX Bourne shell.
For more information on this please refer to :
Difference between sh and bash

invoke shell command from within Aptana/ Eclipse

I'm trying to add a feature to Aptana, and this feature requires that I find out where the gems are on the system. In ruby I would run a command like...
gem_folder_path = `rvm gemdir`
In java obviously there are more factors to deal with, but it seems that the java solution I've been trying to implement won't work within the bounds of the eclipse/ Aptana IDE (I've tested it standalone and it works fine in my helloworld.java file). Are shell commands disabled or something?
Here's my current java solution which is not functional.
public static String getGemsDirectory()
{
try
{
Process proc = Runtime.getRuntime().exec("which ruby");
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(proc.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(proc.getErrorStream()));
String s;
String commandOutput = "";
// read the output from the command
System.out.println("Here is the standard output of the command:\n");
while ((s = stdInput.readLine()) != null) {
//System.out.println(s);
commandOutput += s;
}
// read any errors from the attempted command
System.out.println("Here is the standard error of the command (if any):\n");
while ((String s = stdError.readLine()) != null) {
//System.out.println(s);
commandOutput += s;
}
int statusCode = proc.exitValue();
return commandOutput;
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
return "";
}
}
this tutorial will show u how to run native OS commands. Works for me from Eclipse/Tomcat and just Java
http://www.java-programming.info/tutorial/pdf/java/22-Native-Apps.pdf

how to get error message when excuting java command?

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?

Categories