I'm trying to execute a network testing application via my Java application. Below is the code:
try {
String file = new File("iperf3.exe").getCanonicalPath();
String cmd[] = {file,"-c ping.online.net -P 20 -w 710000 -t"};
Process p = Runtime.getRuntime().exec(cmd);
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while ((line = input.readLine()) != null) {
lblConsole.setText(line);
//System.out.println(line);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I got an error saying that the application could not connect to the server. However, when I execute the command in my command prompt, there is no error.
May I know what could I have missed out here?
Managed to solve this issue. It is mainly on how I executed the code in the cmd. Just updated to as below:
String file = new File("iperf3.exe").getCanonicalPath(); String cmd1[] = {file,"-c","ping.online.net","-P","10","-w","710000"};
Related
I have a Java project that is being built remotely through Jenkins on a Windows server and running some Cucumber tests. Once the tests are finished running, I am creating a process to execute a Putty pscp command to transfer a file over to a linux server. The code works fine when I run it on my local..and it works fine when I manually run the pscp transfer command on the remote windows server where Jenkins is building the project. But for whatever reason when the project is built through Jenkins ...the command is not getting issued. Any ideas? The try Catch is printing out that it successfully has issued the command, however the transferred file is not showing up on the linux server as being updated...so I don't have any failure messages to help me debug this in the output logs.
Some assumptions which I've verified:
The path I'm using for the file that is going to be transferred is correct.
The file is not being transferred.
Some of the code:
String updateJiraLocalPath = System.getProperty("user.dir")+"\\src\\test\\resources\\scripts\\updatejira.sh"; //Eclipse Project path
ProcessBuilder process= new ProcessBuilder("C:\\Putty\\0.6.3\\PSCP.EXE", "-r", "-l", "username#servername", "-pw", "serverPassword", updateJiraLocalPath, "username#servername:/tmp/username/dirToTransferFile");
p = process.start();
try {
final int exitValue = p.waitFor();
if (exitValue == 0){
String line;
System.out.println("Successfully executed the command);
BufferedReader br = new BufferedReader (new InputStreamReader(p.getInputStream()));
while ((line = br.readLine()) != null) {
System.out.println(line);
}
input.close();
}
else {
System.out.println("Failed to execute the 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();
System.out.println(e);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println(e);
}
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 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 have a requirement to export mysql table data to be downloaded by user in CSV format.
To achieve this I am trying java runtime exec function and executing "mysql -e". Unfortunately, I am stuck half way. I am only able to display sql output to console but not able to route it to a file.
WORKING CODE
(I am able to see records in eclipse console)
try {
Process p = Runtime.getRuntime().exec(new String[]
{
"mysql","-h","localhost","-u","admin","-pxyz","myDB","-e", "\"select concat(billing_amount,',') as 'Billing Amount,', concat(amount_paid ,',') as 'Amount Paid,' from invoice\""
}
);
BufferedReader in = new BufferedReader(
new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
//process.waitFor();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
But when I am trying to export data to a file using "> abc.txt ", the file is not created, instead I see the mySQL --help option in eclipse console. What could be wrong here?
CODE NOT WORKING
try {
Process p = Runtime.getRuntime().exec(new String[]
{
"mysql","-h","localhost","-u","admin","-pxyz","myDB","-e", "\"select concat(billing_amount,',') as 'Billing Amount,', concat(amount_paid ,',') as 'Amount Paid,' from invoice\"", "> abc.txt"
}
);
BufferedReader in = new BufferedReader(
new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
//process.waitFor();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I/O redirection is handled by the shell, not by each program. Hence, mysql does not know how to handle > abc.txt. Executing a shell and passing the full command as a single argument like this would work in an Unix system:
Process p = Runtime.getRuntime().exec(new String[] {
"sh", "-c", "mysql -h localhost -u admin -pxyz myDB -e \"select concat(billing_amount,',') as 'Billing Amount,', concat(amount_paid ,',') as 'Amount Paid,' from invoice\" > abc.txt"
});
But the better option, that does not assume an Unix shell, is to use a ProcessBuilder and the redirectOutput(File) method.
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?