Search code examples
javapythonprocessbuilder

Java - How to call python classes using processbuilder


How do I call and execute python class methods from java. My current java code works, but only if I write:

if __name__ == '__main__':
    print("hello")

But I want to execute a class method, regardless of if __name__ == '__main__':

Example python class method I would like to run:

class SECFileScraper:
    def __init__(self):
        self.counter = 5

    def tester_func(self):
        return "hello, this test works"

Essentially I would want to run SECFileScraper.tester_func() in java.

My Java code:

try {

            ProcessBuilder pb = new ProcessBuilder(Arrays.asList(
                    "python", pdfFileScraper));
            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) {
            e.printStackTrace();
        }

pdfFileScraper is the file path to my python script.

I've tried jython, but my python files use pandas and sqlite3, which can't be implemented using jython.


Solution

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