So if I understand your requirement, you want to invoke a class method in pdfFileScraper.py. The basics of doing this from the shell would be something akin to:
scraper=path/to/pdfFileScraper.py
dir_of_scraper=$(dirname $scraper)
export PYTHONPATH=$dir_of_scraper
python -c 'import pdfFileScraper; pdfFileScraper.ClassInScraper()'
What we do is get the directory of pdfFileScraper, and add it to the PYTHONPATH, then we run python with a command that imports the pdfFileScraper file as a module, which exposes all the methods and classes in the class in the namespace pdfFileScraper, and then construct a class ClassInScraper().
In java, something like:
import java.io.*;
import java.util.*;
public class RunFile {
public static void main(String args[]) throws Exception {
File f = new File(args[0]); // .py file (e.g. bob/script.py)
String dir = f.getParent(); // dir of .py file
String file = f.getName(); // name of .py file (script.py)
String module = file.substring(0, file.lastIndexOf('.'));
String command = "import " + module + "; " + module + "." + args[1];
List<String> items = Arrays.asList("python", "-c", command);
ProcessBuilder pb = new ProcessBuilder(items);
Map<String, String> env = pb.environment();
env.put("PYTHONPATH", dir);
pb.redirectErrorStream();
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);
}
}
}
Answer from Anya Shenanigans on Stack OverflowJava - How to call python classes using processbuilder - Stack Overflow
Java ProcessBuilder not able to run Python script in Java - Stack Overflow
calling python method through java ProcessBuilder() - Stack Overflow
How to start a python process from Java and do IO communication?
So if I understand your requirement, you want to invoke a class method in pdfFileScraper.py. The basics of doing this from the shell would be something akin to:
scraper=path/to/pdfFileScraper.py
dir_of_scraper=$(dirname $scraper)
export PYTHONPATH=$dir_of_scraper
python -c 'import pdfFileScraper; pdfFileScraper.ClassInScraper()'
What we do is get the directory of pdfFileScraper, and add it to the PYTHONPATH, then we run python with a command that imports the pdfFileScraper file as a module, which exposes all the methods and classes in the class in the namespace pdfFileScraper, and then construct a class ClassInScraper().
In java, something like:
import java.io.*;
import java.util.*;
public class RunFile {
public static void main(String args[]) throws Exception {
File f = new File(args[0]); // .py file (e.g. bob/script.py)
String dir = f.getParent(); // dir of .py file
String file = f.getName(); // name of .py file (script.py)
String module = file.substring(0, file.lastIndexOf('.'));
String command = "import " + module + "; " + module + "." + args[1];
List<String> items = Arrays.asList("python", "-c", command);
ProcessBuilder pb = new ProcessBuilder(items);
Map<String, String> env = pb.environment();
env.put("PYTHONPATH", dir);
pb.redirectErrorStream();
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);
}
}
}
You can also call Python lib directly via JNI. This way, you don't start new process, you can share context between script calls, etc.
Take a look here for a sample:
https://github.com/mkopsnc/keplerhacks/tree/master/python
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);}
}
}
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.
I don't think reading the executable (a series of binary numbers) will do any good. Also, The class java.lang.ProcessBuilder, in Java 1.5, is used to create operating system processe. Instead you should use the jython API: http://www.jython.org/javadoc/org/python/util/PythonInterpreter.html
Particularly: PyInstance and PythonInterpreter;
Actually, you can't call a Python function from a ProcessBuilder, but you can create a Python program which calls a function from your Python module. And than you can run it from a ProcessBuilder as a command:
python -c 'from pickel4output import pic; pic()'
However, take into attention that since your pic function expects some parameters, you have to create a python code which reads these parameters from a file or a command line and then run the function.
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
Try to use PrecessBuilder -
try{
String prg = "import sys\nprint int(sys.argv[1])+int(sys.argv[2])\n";
BufferedWriter out = new BufferedWriter(new FileWriter("test1.py"));
out.write(prg);
out.close();
int number1 = 10;
int number2 = 32;
ProcessBuilder pb = new ProcessBuilder("python","test1.py",""+number1,""+number2);
Process p = pb.start();
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
int ret = new Integer(in.readLine()).intValue();
System.out.println("value is : "+ret);
}catch(Exception e){System.out.println(e);}
See here from more detail.
The easiest way to integrate a Java application with Python is to use Jython.
I have used this successfully in the past to build scriptable java applications before we had access to Nashorn and it's ilk.