Usually when executing commands using ProcessBuilder, PATH variable is not taken into consideration. Your python C:/Machine_Learning/Text_Analysis/Ontology_based.py is directly working in your CMD shell because it can locate the python executable using the PATH variable. Please provide the absolute path to python command in your Java code. In below code replace <Absolute Path to Python> with the path to python command and its libraries. Usually it will something like C:\Python27\python in Windows by default
package text_clustering;
import java.io.*;
public class Similarity {
/**
*
* @param args
*
*/
public static void main(String[] args){
try{
String pythonPath = "C:/Machine_Learning/Text_Analysis/Ontology_based.py";
//String pythonExe = "C:/Users/AppData/Local/Continuum/Anaconda/python.exe";
ProcessBuilder pb = new ProcessBuilder(Arrays.asList("<Absolute Path to Python>/python", pythonPath));
Process p = pb.start();
BufferedReader bfr = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
System.out.println("Running Python starts: " + line);
int exitCode = p.waitFor();
System.out.println("Exit Code : "+exitCode);
line = bfr.readLine();
System.out.println("First Line: " + line);
while ((line = bfr.readLine()) != null){
System.out.println("Python Output: " + line);
}
}catch(Exception e){System.out.println(e);}
}
}
Answer from shazin on Stack OverflowUsually when executing commands using ProcessBuilder, PATH variable is not taken into consideration. Your python C:/Machine_Learning/Text_Analysis/Ontology_based.py is directly working in your CMD shell because it can locate the python executable using the PATH variable. Please provide the absolute path to python command in your Java code. In below code replace <Absolute Path to Python> with the path to python command and its libraries. Usually it will something like C:\Python27\python in Windows by default
package text_clustering;
import java.io.*;
public class Similarity {
/**
*
* @param args
*
*/
public static void main(String[] args){
try{
String pythonPath = "C:/Machine_Learning/Text_Analysis/Ontology_based.py";
//String pythonExe = "C:/Users/AppData/Local/Continuum/Anaconda/python.exe";
ProcessBuilder pb = new ProcessBuilder(Arrays.asList("<Absolute Path to Python>/python", pythonPath));
Process p = pb.start();
BufferedReader bfr = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
System.out.println("Running Python starts: " + line);
int exitCode = p.waitFor();
System.out.println("Exit Code : "+exitCode);
line = bfr.readLine();
System.out.println("First Line: " + line);
while ((line = bfr.readLine()) != null){
System.out.println("Python Output: " + line);
}
}catch(Exception e){System.out.println(e);}
}
}
Reading from stdin returns null when the script is killed/dies. Do a Process#waitFor and see what the exitValue is. If it isn't 0 then it's highly probable that your script is dying.
I'd try making it work with a dumb script that only writes a value. Make sure that you print all error information from python.
How to start a python process from Java and do IO communication?
python - Running a .py file from Java - Stack Overflow
Call and receive output from Python script in Java? - Stack Overflow
Running python from Java using Process Builder - Stack Overflow
I'm a python dev, like I know literally no Java. But because I'm experienced in python I can at least kinda understand what I'm doing in Java. But I'm stuck on this. I know it's basic shit, I can do this in python, but I just can't read the language so I can't read any help or guides either.
All I need to do really is start a python program from Java as a subprocess, receive it's output stream and be able to send to its input stream.
The python program is a discord bot using async/await stuff and will run continuously so it needs to be uninterrupted, like if it was run from the terminal EXCEPT the Java program can send input and receive output.
I also suck att processes and stuff (this is on Windows btw) and as I said I suck at Java too so sorry if I gave to little information or something. Just tell me if that's the case.
Thanks in advance :D
You can use like this also:
String command = "python /c start python path\to\script\script.py";
Process p = Runtime.getRuntime().exec(command + param );
or
String prg = "import sys";
BufferedWriter out = new BufferedWriter(new FileWriter("path/a.py"));
out.write(prg);
out.close();
Process p = Runtime.getRuntime().exec("python path/a.py");
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String ret = in.readLine();
System.out.println("value is : "+ret);
Run Python script from Java
I believe we can use ProcessBuilder
Runtime.getRuntime().exec("python "+cmd + py + ".py");
.....
//since exec has its own process we can use that
ProcessBuilder builder = new ProcessBuilder("python", py + ".py");
builder.directory(new File(cmd));
builder.redirectError();
....
Process newProcess = builder.start();
Not sure if I understand your question correctly, but provided that you can call the Python executable from the console and just want to capture its output in Java, you can use the exec() method in the Java Runtime class.
Process p = Runtime.getRuntime().exec("python yourapp.py");
You can read up on how to actually read the output from this resource: http://www.devdaily.com/java/edu/pj/pj010016 import java.io.*;
public class JavaRunCommand {
public static void main(String args[]) {
String s = null;
try {
// run the Unix "ps -ef" command
// using the Runtime exec method:
Process p = Runtime.getRuntime().exec("ps -ef");
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(p.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);
}
System.exit(0);
}
catch (IOException e) {
System.out.println("exception happened - here's what I know: ");
e.printStackTrace();
System.exit(-1);
}
}
}
There is also an Apache library (the Apache exec project) that can help you with this. You can read more about it here:
http://www.devdaily.com/java/java-exec-processbuilder-process-1
http://commons.apache.org/exec/
You can include the Jython library in your Java Project. You can download the source code from the Jython project itself.
Jython does offers support for JSR-223 which basically lets you run a Python script from Java.
You can use a ScriptContext to configure where you want to send your output of the execution.
For instance, let's suppose you have the following Python script in a file named numbers.py:
for i in range(1,10):
print(i)
So, you can run it from Java as follows:
public static void main(String[] args) throws ScriptException, IOException {
StringWriter writer = new StringWriter(); //ouput will be stored here
ScriptEngineManager manager = new ScriptEngineManager();
ScriptContext context = new SimpleScriptContext();
context.setWriter(writer); //configures output redirection
ScriptEngine engine = manager.getEngineByName("python");
engine.eval(new FileReader("numbers.py"), context);
System.out.println(writer.toString());
}
And the output will be:
1
2
3
4
5
6
7
8
9
As long as your Python script is compatible with Python 2.5 you will not have any problems running this with Jython.
Use the newer ProcessBuilder class:
ProcessBuilder pb = new ProcessBuilder("python","Refresh.py");
Process p = pb.start();
Hope that works for you!
You are not checking for errors from the python script. You can achieve this simply by merging STDERR to STDOUT and reporting the content of STDOUT to console:
Process p = new ProcessBuilder("python", "Refresh.py")
.redirectErrorStream(true)
.start();
p.getInputStream().transferTo(System.out);
int rc = p.waitFor();
This should print out the error message from python and give you error code back. You may have problems with path to files, so you might need to adjust your arguments to explicit pathnames to "python" and/or "Refresh.py".
You can check the ProcessBuilder documentation over at Sunoracle, but basically, you can run the interpreter for the scripting language and pass the script you want to run to it.
For example, let's say you have a script in /home/myuser/py_script.py, and python is in /usr/bin/
class ProcessRunner
{
public static void main(String [] args)
{
ProcessBuilder pb = new ProcessBuilder("/usr/bin/python", "/home/myuser/py_script.py");
Process p = pb.start();
}
}
An extremely basic example, you can get fancier with changing the working directory and change the environment.
You can also construct ProcessBuilder with a String array or a subtype of List<String>. The first item in the list should be the program/executable you want to run, and all the following items are arguments to the program.
String pbCommand[] = { "/usr/bin/python", "/home/myuser/py_script.py" };
ProcessBuilder pb = new ProcessBuilder(pbCommand);
Process p = pb.start();
To avoid having to manually enter the entire location of the script, which may also result in portability issues, here's what I did:
String pwd = System.getProperty("user.dir");
ProcessBuilder pb = new ProcessBuilder("/usr/bin/python", pwd+'/'+scriptName, arg1, arg2);
Process p = pb.start();