I'm trying to run an external program in java like this:
Process p = Runtime.getRuntime().exec("./shufflet 1 2 <in.seq> out.seq");
BufferedReader bri = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader bre = new BufferedReader(new InputStreamReader(p.getErrorStream()));
String line;
while ((line = bri.readLine()) != null) {
System.out.println(line);
}
bri.close();
while ((line = bre.readLine()) != null) {
System.out.println(line);
}
bre.close();
p.waitFor();
Basically, this program that I'm executing (Shufflet) reads in whatever is in in.seq and then writes something to out.seq based on that.
If I copy+paste that line (./shufflet 1 2 <in.seq> out.seq) to the command line it works fine.
If I execute the java program it outputs Usage: shufflet [OPTIONS] NSEQ ORDER <INFILE >OUTFILE which is the error message that Shufflet gives if the parameters are wrong.
I know the parameters are correct because, again, it works if I copy+paste it to the command line.
Any ideas?
Have you tried with DataInputStream ?
DataInputStream myStream = new DataInputStream(p.getInputStream());
while ((line = myStream.readLine()) != null) {
System.out.println(line);
}
Related
I want to use this script in my java app: https://github.com/jcapona/amazon-wishlist-scraper.
I've looked around and I tried executing the script like so:
public static void main(String[] args) throws IOException {
String s = null;
Process p = Runtime.getRuntime().exec("python C:\\\\Users\\\\Home\\\\work\\\\test.py");
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(p.getInputStream()));
while ((s=stdInput.readLine()) != null) {
System.out.println(s);
}
}
But I am not getting any output. What do I need to be able to run this specific script?
You can use like this :
String command = "python /c start python path\to\script\script.py>";
Process p = Runtime.getRuntime().exec(command);
p.waitFor();
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(p.getInputStream()));
BufferedReader stdErr = new BufferedReader(new InputStreamReader(p.getErrorStream()));
String line;
while ((line = stdInput.readLine()) != null) {
System.out.println(line);
}
stdInput.close();
while ((line = stdErr.readLine()) != null) {
System.out.println(line);
}
stdErr.close();
p.waitFor();
System.out.println("Done.");
p.destroy();
Protip: Always copy your path from the file explorer tab
And since you are getting JSON response try GSON library to parse it.
And if you want to work heavily on python using java, try exploring Jython
I am trying to get return value from python script into Java using ProcessBuilder. I am expecting the value "This is what I am looking for" in Java. Can anyone point me as to what is wrong in below logic?
I am using python3 and looking to have this done using java standard libraries.
test.py code
import sys
def main33():
return "This is what I am looking for"
if __name__ == '__main__':
globals()[sys.argv[1]]()
Java code
String filePath = "D:\\test\\test.py";
ProcessBuilder pb = new ProcessBuilder().inheritIO().command("python", "-u", filePath, "main33");
Process p = pb.start();
int exitCode = p.waitFor();
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
line = in.readLine();
while ((line = in.readLine()) != null){
line = line + line;
}
System.out.println("Process exit value:"+exitCode);
System.out.println("value is : "+line);
in.close();
output
Process exit value:0
value is : null
When you spawn a process from another process, they can only (mostly rather) communicate through their input and output streams. Thus you cannot expect the return value from main33() in python to reach Java, it will end its life within Python runtime environment only. In case you need to send something back to Java process you need to write that to print().
Modified both of your python and java code snippets.
import sys
def main33():
print("This is what I am looking for")
if __name__ == '__main__':
globals()[sys.argv[1]]()
#should be 0 for successful exit
#however just to demostrate that this value will reach Java in exit code
sys.exit(220)
public static void main(String[] args) throws Exception {
String filePath = "D:\\test\\test.py";
ProcessBuilder pb = new ProcessBuilder()
.command("python", "-u", filePath, "main33");
Process p = pb.start();
BufferedReader in = new BufferedReader(
new InputStreamReader(p.getInputStream()));
StringBuilder buffer = new StringBuilder();
String line = null;
while ((line = in.readLine()) != null){
buffer.append(line);
}
int exitCode = p.waitFor();
System.out.println("Value is: "+buffer.toString());
System.out.println("Process exit value:"+exitCode);
in.close();
}
You're overusing the variable line. It can't be both the current line of output and all the lines seen so far. Add a second variable to keep track of the accumulated output.
String line;
StringBuilder output = new StringBuilder();
while ((line = in.readLine()) != null) {
output.append(line);
.append('\n');
}
System.out.println("value is : " + output);
This question already has answers here:
Can't run program with ProcessBuilder, runs fine from command line
(2 answers)
Closed 5 years ago.
I am trying to write an utility java program that calls a perl script in unix box and shows the output of the script. The issue is when I am executing command2,
String[] command2 = {"/archive/scripts/grep.pl", "/apps/ws/logs/api.log"};
the output is coming correctly. But when i am using command1,
String[] command1 = {"/archive/scripts/grep.pl", "/apps/ws/logs/*"};
i am getting the below exception:
Can't open /apps/ws/logs/*: No such file or directory at /archive/scripts/grep.pl line 160.
Below is the full code for your reference:
StringBuffer output = new StringBuffer();
try {
ProcessBuilder processBuilder = new ProcessBuilder(command1);
LOGGER.debug("Command: "+processBuilder.command());
Process process = processBuilder.start();
process.waitFor();
BufferedReader br;
if (process.exitValue() == 0) {
LOGGER.debug("Inside if block. Exit value: "+process.exitValue());
String line;
br = new BufferedReader(new InputStreamReader(process.getErrorStream()));
while ((line = br.readLine()) != null) {
output.append(line + "\n");
}
} else {
LOGGER.debug("Inside Else block. Exit value: "+process.exitValue());
br = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = br.readLine()) != null) {
output.append(line + "\n");
}
}
} catch (Exception e) {
LOGGER.debug("Exception thrown"+e.getStackTrace());
output.append(e.getStackTrace().toString());
e.printStackTrace();
}
return output.toString();
I am not able to understand what is the issue. Is there any way to accomplish this.
Use a command shell to interpret the wildcard
String[] command1 = {"bash", "-c", "/archive/scripts/grep.pl /apps/ws/logs/*"};
I executed this code:
Process proc = Runtime.getRuntime().exec("cat /home/uhf/metrics.sh");
System.out.println(proc.toString());
String proc1 = proc.toString();
But I am not able to get the content of kafka_metrics.sh. Instead I am getting java.lang.UNIXProcess#5fd0d5ae as output. What should I include so that I can get the content of that file?
May this is what you are looking for.
Process proc = Runtime.getRuntime().exec("cat /home/uhf/metrics.sh");
String s = 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");
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);
}
You are printing the Process object.
to get the content of the executed process you need to take the input stream and pass that stream to the reader
Process process = Runtime.getRuntime().exec("cat /home/uhf/metrics.sh");
InputStream is = process.getInputStream();
try (BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
br.lines().forEach(System.out::println);
}
in my java program, i am trying to get the InputStream from a process and print it with this piece of code:
try {
Process p = Runtime.getRuntime().exec("cmd /c start dammage\\4.simulation.cmd");
//BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
//StringBuffer sb = new StringBuffer();
//String line;
//while ((line = br.readLine()) != null) {
//sb.append(line).append("\n");
//}
//System.out.println(sb.toString());
String input = IOUtils.toString(p.getErrorStream());
System.out.println(input);
} catch (IOException ex) {
Logger.getLogger(UI.class.getName()).log(Level.SEVERE, null, ex);
JOptionPane.showMessageDialog(this, "Something happened");
}
I tried both ways shown above (commented and uncommented), but none of them prints anything. So i would like to ask what am i doing wrong here?
I appreciate any help.
The buffered reader solution looks fine. You might be looking in the wrong stream. Try getting from both streams.. Like
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
StringBuffer sb = new StringBuffer();
String line;
//Read the output from the command
while ((line = stdInput.readLine()) != null) {
sb.append(line).append("\n");
}
//read any errors from the attempted command
while ((line = stdError.readLine()) != null) {
sb.append(line).append("\n");
}
Are you sure it should print something? Because, the commented code should work just right provided the command executed is returning non-empty input stream. Try replacing the argument of exec to "cmd". And see if it's able to read from the input stream. Do following. On windows machine it should give you welcome message from cmd (the usual welcome message we get after we run start command prompt).
Process p = Runtime.getRuntime().exec("cmd");
About the uncommented code, How IOUtils work? Does it read from the error stream repeatedly. Because, IMO, it's just one time read and not the repetitive one.
Hope I don't confuse.
You should add a p.waitFor(); to give the program time to terminate. Also, verify if you really want to read stdout or stderr
This works for me:
Process p = Runtime.getRuntime().exec("cmd /c java -version");
int ret = p.waitFor();
System.out.println("process terminated with return code: " + ret);
BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream()));
StringBuffer sb = new StringBuffer();
String line;
while((line = br.readLine()) != null) {
sb.append(line).append("\n");
}
System.out.println(sb.toString());