ninia / jep

Embed Python in Java
Other
1.3k stars 147 forks source link

How to call .py module from Java code? #393

Closed Daniel-Alievsky closed 2 years ago

Daniel-Alievsky commented 2 years ago

I successfully created a simple JEP Java test, which interprets some Python script, like in your documentation:

interp.exec("from java.lang import System"); interp.exec("s = 'Hello World'"); etc.

However I need not just to interpret some very little script, but load .py module, which will load other .py modules, etc.

I've tried to write:

public class SimpleJepForModule {
    public static void main(String[] args) {
        try (Interpreter interp = new SharedInterpreter()) {
            interp.exec("import SimpleJepTestAB as TestAB");
            interp.exec("TestAB.b(");
        }
    }
}

SimpleJepTestAB.py file:

def b():
    print("ababab")

Results: java -classpath ../../target/test-classes;../../target/classes;C:\Users\Daniel.m2\repository\black\ninia\jep\4.0.3\jep-4.0.3.jar com.siams.stare.extensions.python.tests.SimpleJepForModule Exception in thread "main" jep.JepException: <class 'ModuleNotFoundError'>: No module named 'SimpleJepTestAB' at .(:1) at jep.Jep.exec(Native Method) at jep.Jep.exec(Jep.java:339) at com.siams.stare.extensions.python.tests.SimpleJepForModule.main(SimpleJepForModule.java:9) (SimpleJepTestAB.py is located in the folder, from which I call "java..." command.)

Where should I place SimpleJepTestAB.py to allow Java code to find it? How can I inform the SharedInterpreter where is the root of the hierarchy of my Python files?

ctrueden commented 2 years ago

@Daniel-Alievsky It's going to depend on your sys.path, the same as with non-jep Python. It should work to put your SimpleJepTestAB.py file in any of the directories shown by import sys; print(sys.path). Note that . is typically included in sys.path, so if you put SimpleJepTestAB.py in your current working directory, that should also work; I tested it quickly and it worked for me. Alternately, you could import sys; sys.path.append("/root/of/the/hierarchy") before importing.

Daniel-Alievsky commented 2 years ago

Thank you, now it works. Really, in my configuration there was no . path in sys.path I added the following to my Java test, and all start working:

            interp.exec("import sys");
            interp.exec("sys.path.append('/siams/computer-vision/stare-python-experiments/jep-java-tests/src/test/python')");

Of course, in production application this path will be loaded from some other project settings like system properties.