setting import module path in Jython - strange beh

2020-06-22 19:10发布

问题:

I'm building Java to Jython bridge class. The task I'm trying to solve is to make Jython to look for python modules in my application working directory (also known as program execution directory).

I'm doing so by appending System.getProperty("user.dir") value to the sys.path:

pySysState = new PySystemState();
//add working directory into sys.path
pySysState.path.append(new PyString(System.getProperty("user.dir")));
log_.info("Jython sys state initialized. sys.path: " + this.pySysState.path);

I get ImportError exception:

python module 'user_module' was not found. sys.path: ['<other jars>\\Lib', '/<path to jython>/Lib', '__classpath__', '__pyclasspath__/', 'C:\\Users\\vvlad\\IDEAProjects\\transform']
ImportError: No module named scheduled_helper

at org.python.core.Py.ImportError(Py.java:290)
at org.python.core.imp.import_first(imp.java:750)
at org.python.core.imp.import_name(imp.java:834)
    ...

Where C:\\Users\\vvlad\\IDEAProjects\\transform is application directory.

In sys.path looks like that:

Import works fine when I manually specify full path to working directory in Jython registry python.path variable. And sys.path looks different:

>>sys.path: ['C:\\Users\\vvlad\\IDEAProjects\\transform', '<other jars path>\\Lib', '/<path to jython>/jython-2.5.2.jar/Lib', '__classpath__', '__pyclasspath__/', ]

So import works fine when working directory comes as a first entry in sys.path. But fails when working directory is the last entry.

I'm using Jython 2.5.2 and run tests on Windows machine from IntelliJ IDEA environment.

Plan B for me would be to set Jython registry python.path with user.dir value before initializing PySysState - but this would introduce some hidden behavior.

回答1:

Here is code for setting registry python.path value with user.dir in your code (Plan B I mentioned in the question):

Here is how you initialize PySysState:

props = setDefaultPythonPath(props);
PySystemState.initialize( System.getProperties(), props, null );

setDefaultPythonPath method:

/**
 * Adds user.dir into python.path to make Jython look for python modules in working directory in all cases
 * (both standalone and not standalone modes)
 * @param props
 * @return props
 */
private Properties setDefaultPythonPath(Properties props) {
    String pythonPathProp = props.getProperty("python.path");
    String new_value;
    if (pythonPathProp==null)
    {
        new_value  = System.getProperty("user.dir");
    } else {
        new_value = pythonPathProp +java.io.File.pathSeparator + System.getProperty("user.dir") + java.io.File.pathSeparator;
    }
    props.setProperty("python.path",new_value);
    return props;
}