Question

Following Using Jython Within Java Applications, I could integrate Java and Jython (Java methods can call python scripts). The python code is located inside py directory. The Jython uses sys.path.append("py") command to find the Jython scripts.

Then, I tried to integrate all the files into a single jar file.

For the pre step, I could generate one jar file, and copied the py directory along side with the jar file, and it works fine. I used IntelliJ IDEA for generating a jar file.

│   └── py
│       ├── Context$py.class
│       ├── Context.py
│       ├── Host$py.class
│       └── Host.py
├── aggregationPython.jar <-- Generated jar file 

For the next step, I tried to copy the py directory inside the jar file, I also used IntelliJ for that.

I checked that the jar file has the py directory in the jar file. You see that the py directory is located at the root of jar file.

enter image description here

However, when I executed the jar file, I got an error saying the jython module is missing.

> java -jar aggregationPython.jar 
Exception in thread "main" ImportError: No module named Host

What might be wrong? I assumed the py directory can be stored in a jar file to be found just like it is found outside the jar file. What's wrong with this assumption?

Was it helpful?

Solution

The Jython Class files are in the jar file, and the search path for Jython doesn't care if they are in jar file or not. All we need is to locate where the Jython classes are, and let Jython know about it.

From the hint of this post(How to get the path of a running JAR file?), one can find the path where the jar file is located. The class files can be found in the location + "py" directory.

For development purposes, the Jython source code in the source directory should also be specified ("src/py").

enter image description here

String runningDir = Simulate.class.getProtectionDomain().getCodeSource().getLocation().getPath();
String jarPointer = "py";
String joinedPath = new File(runningDir, jarPointer).toString();

String pythonSrcPath = "/Users/smcho/code/PycharmProjects/aggregator/src";
JythonObjectFactory.setupPath(new String[]{joinedPath, "src/py"});

After this modification, the Jython could find the classes correctly.

This is the setupPath method for setting up Jython search path.

public static void setupPath(String[] paths)
{
    PythonInterpreter interpreter = new PythonInterpreter();

    interpreter.exec("import sys;");
    for (int i = 0; i < paths.length; i++) {
        interpreter.exec(String.format("sys.path.append(\"%s\")", paths[i]));
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top