Java Runtime.getRuntime().exec Executing only first line - java

I want to execute a python script from java.
The code is getting in to the python file but only executes first line of the file.
following is the code:
Process p = Runtime.getRuntime().exec("python "+dir+"/pyfiles/testfile.py");
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
value = in.readLine();
after the first line nothing is executed.
what is the solution?
'dir' value is getting from
final String dir = System.getProperty("user.dir");
link to python file:
https://drive.google.com/file/d/1tvkFTM_Oo5gTS7FyzeNgoeY5DLitFQjD/view?usp=sharing

The problem seems, that you are only reading the first line of your BufferedReader. So change your code as follows:
Process p = Runtime.getRuntime().exec("python "+dir+"/pyfiles/testfile.py");
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = in.readLine()) != null)
{
System.out.println(line);
}

it worked fine when I passed like this:
String cmd = "python2.7 "+dir+"/pyfiles/getGitFiles.py "+ownerVal+" "+repoVal+" "+folderVal+" "+branchVal+" "+Values.accessToken;
System.out.println(cmd);
Process p = Runtime.getRuntime().exec(cmd);
passing the arguments inside the 'exec' itself is causing the problem.

Related

How to return value from Python script to Java using ProcessBuilder?

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);

Python on Jar - Running python Script after process end in Java

I want to run a python script(tensorflow's Image label script) after RPi's camera module captures a photo using a jar file. I have tried both Runtime and ProcessBuilder, but it says no file or Directory found.
Here's my Code for the Runtime Code:
Process rt = Runtime.getRuntime().exec("python3 -m scripts.image-label.py");
rt.waitFor();
BufferedReader in = new BufferedReader(new InputStreamReader(rt.getInputStream()));
String read = in.readLine();
ML = read;
result resfin = new result();
resfin.setVisible(true);
And here's the code for my ProcessBuilder one:
ProcessBuilder builder = new ProcessBuilder("/home/pi/Desktop/ML/scripts/image-label.py");
Process np = builder.start();
np.waitFor();
BufferedReader in = new BufferedReader(new InputStreamReader(np.getInputStream()));
String read = in.readLine();
ML = read;
result resfin = new result();
resfin.setVisible(true);
Am i doing something wrong? Or am i missing something? Any help would be appreciated!
I have tried with the following code, it is working fine, though I have not tried with -m "module" flag, since I do not know how to create a module file in python.
Found some of the issues with code:
1. You need to pass python3 as an argument to process builder as shown below
2. Provide an absolute path for a python file.
3. You can use either of Runtime or ProcessBuilder without an issue.
// Process rt = Runtime.getRuntime().exec("python3 -m /Users/<user-name>/demo/JavaNotepad/src/main/java/com/mypython.py");
ProcessBuilder builder = new ProcessBuilder("python3", "-m", "/Users/<user-name>/demo/JavaNotepad/src/main/java/com/mypython.py");
Process rt = builder.start();
int exitCode = rt.waitFor();
System.out.println("Process exited with : " + exitCode);
BufferedReader in = new BufferedReader(new InputStreamReader(rt.getInputStream()));
BufferedReader err = new BufferedReader(new InputStreamReader(rt.getErrorStream()));
System.out.println("Python file output:");
String line;
BufferedReader reader;
if (exitCode != 0) {
reader = err;
} else {
reader = in;
}
while ((line = reader.readLine()) != null) {
System.out.println(line);
}

Call python script (part of Anaconda package) from Java

I am trying to trigger python code from a java scheduler. In standalone mode, we execute the python script via conda prompt, it takes arguments and returns value in JSON. How do I call this from a Java program and capture the output? Please help
You can use the Runtime to execute your command. Check the doc as well.
Here is an example how you can use it:
Process process = Runtime.getRuntime().exec("ls -al");
StringBuilder sb = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
String read;
while ((read = br.readLine()) != null) {
sb.append(read);
}
br.close();
System.out.println(sb.toString());
You should be using Java's ProcessBuilder to open a command line and execute your python script. Code should look like as follows (adapted to linux OS so change the command line if you're on Windows):
//create a command line to execute python script
ProcessBuilder builder = new ProcessBuilder("python", "scriptname.py", "param1", "param2", ...);
builder.redirectErrorStream(true);
Process p = builder.start();
//read output
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
StringBuilder sb = new StringBuilder();
while ((line = br.readLine()) != null) {
sb.append(line);
}
//convert output to JSON
Gson gson = new Gson();
Type type = new TypeToken<YourType>(){}.getType();
YourType obj = gson.fromJson(line, type);

Calling jar from terminal vs calling jar from class file

I have a problem where I can successfully call the jar file from the terminal but I can't call it successfully from another Java file. As you can see it works properly from the terminal.
However, it returns null when called from a class file despite feeding in the same arguments.
The relevant bit of code would appear to call the jar file the same way.
try{
String output = "java -jar Translator.jar " + word;
Process p = Runtime.getRuntime().exec(output);
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = in.readLine();
System.out.println(line);
while ((line = in.readLine())!= null) {
line = in.readLine();
line = line.trim();
System.out.println(line);
}
}

Writing the Output of an Operating System Command to the Console

I want to execute an operating system command in Java, and then print out it's returned value. Like this:
This is what I am trying...
String location_of_my_exe_and_some_parameters = "c:\\blabla.exe /hello -hi";
Runtime.getRuntime().exec(location_of_my_exe_and_some_parameters);
I tried putting a System.out.print() on the beginning of my Runtime... line, but it failed. Because, apparently, getRuntime() returns a Runtime object.
Now, the problem is, when I execute the "blabla.exe /hello -hi" command in command line, I got a result like: "You executed some command, hurray!". But, in Java, I got nothing.
I tried putting the return value into a Runtime object, to an Object object. However, they both failed. How can I accomplish this?
Problem Solved - this is my solution
Process process = new ProcessBuilder(location, args).start();
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
Notice that Runtime.exec(...) returns a Process object. You can use this object to capture its input stream and retrieve whatever it prints to the standard output:
Process p = Runtime.getRuntime().exec(location_of_my_exe_and_some_parameters);
InputStream is = p.getInputStream();
// read process output from is
You can capture the output of a command using this:
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec(command);
BufferedReader input = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line=null;
while((line=input.readLine()) != null) {
log.info(line);
}
//This will wait for the return code of the process
int exitVal = pr.waitFor();
UseProcessBuilder instead of Runtime.
Like:
Process process = new ProcessBuilder("c:\\blabla.exe","param1","param2").start();
Answer:
Process process = new ProcessBuilder("c:\\blabla.exe","/hello","-hi").start();
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
System.out.printf("Output of running %s is:", Arrays.toString(args));

Categories