Christine VACHER
Christine VACHER

Reputation: 137

ImportError: Cannot import site module and its dependencies: No module named site

I am trying to run jython servlets on Windows. I can’t run even the most simple HelloWorld.py. I get the following 500 error:

message Servlet.init() for servlet [PyServlet] threw exception
 ...
description Le serveur a rencontré une erreur interne qui l''a empêché de satisfaire la requête.
exception
javax.servlet.ServletException: Servlet.init() for servlet [PyServlet] threw exception
 ...
cause mère
ImportError: Cannot import site module and its dependencies: No module named site
Determine if the following attributes are correct:
  * sys.path: ['C:\\apache-tomcat-8.5.24\\webapps\\jython\\WEB-INF\\lib\\Lib', '__classpath__', '__pyclasspath__/']
    This attribute might be including the wrong directories, such as from CPython
  * sys.prefix: C:\apache-tomcat-8.5.24\webapps\jython\WEB-INF\lib
    This attribute is set by the system property python.home, although it can
    be often automatically determined by the location of the Jython jar file

You can use the -S option or python.import.site=false to not import the site module

    org.python.core.Py.ImportError(Py.java:328)
    org.python.core.Py.importSiteIfSelected(Py.java:1563)
    org.python.util.PythonInterpreter.<init>(PythonInterpreter.java:116)
 ...

Jython is deployed under C:\jython2.7.0

My very basic webapp is under C:\apache-tomcat-8.5.24\webapps\jython

jython.jar (not the standalone jar) is copied asC:\apache-tomcat-8.5.24\webapps\jython\WEB-INF\lib\jython.jar

My web.xmlis taken from http://www.jython.org/javadoc/org/python/util/PyServlet.html:

<!-- C:\apache-tomcat-8.5.24\webapps\jython\WEB-INF\web.xml -->
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="3.1">
   <servlet> 
        <servlet-name>PyServlet</servlet-name> 
        <servlet-class>org.python.util.PyServlet</servlet-class> 
         <init-param> 
            <param-name>python.home</param-name> 
            <param-value>C:\\jython2.7.0</param-value> 
        </init-param> 
       <load-on-startup>1</load-on-startup> 
    </servlet> 
    <servlet-mapping> 
        <servlet-name>PyServlet</servlet-name> 
        <url-pattern>*.py</url-pattern> 
    </servlet-mapping> 
 </web-app>

The error message says it, the wrong directory is included in sys.path. python.home is not taken from my initialization parameter (why so?), it is guessed from the location of jython.jar.

PyServlet initialization

I had a look at the initialization code for PyServlet:

@Override
public void init() {
    Properties props = new Properties();
    // Config parameters
    Enumeration<?> e = getInitParameterNames();
    while (e.hasMoreElements()) {
        String name = (String)e.nextElement();
        props.put(name, getInitParameter(name));
    }
     // ...
        init(props, getServletContext());
    }
    reset();
}

/**
 * PyServlet's initialization can be performed as a ServletContextListener or as a regular
 * servlet, and this is the shared init code. If both initializations are used in a single
 * context, the system state initialization code only runs once.
 */
protected static void init(Properties props, ServletContext context) {
    String rootPath = getRootPath(context);
    context.setAttribute(INIT_ATTR, true);
    Properties baseProps = PySystemState.getBaseProperties();
    // Context parameters
    Enumeration<?> e = context.getInitParameterNames();
    while (e.hasMoreElements()) {
        String name = (String)e.nextElement();
        props.put(name, context.getInitParameter(name));
    }
    if (props.getProperty("python.home") == null
            && baseProps.getProperty("python.home") == null) {
        props.put("python.home", rootPath + "WEB-INF" + File.separator + "lib");
    }
    PySystemState.initialize(baseProps, props, new String[0]);
    // ...
    PySystemState.add_classdir(rootPath + "WEB-INF" + File.separator + "classes");
    PySystemState.add_extdir(rootPath + "WEB-INF" + File.separator + "lib", true);
}

I would expect the python.home initialization parameter to be added as a property and that property to be used to construct the sys.path as shown in the JavaDoc!

What am I missing?

Upvotes: 5

Views: 11966

Answers (4)

Shehan Simen
Shehan Simen

Reputation: 1306

As someone suggested. I used jython-standalone and works well.

<dependency>
     <groupId>org.python</groupId>
     <artifactId>jython-standalone</artifactId>
     <version>2.7.2</version>
</dependency>

@Test
public void givenPythonScript_whenPythonProcessInvoked_thenSuccess() throws Exception {
    PythonInterpreter interpreter = new PythonInterpreter();
    interpreter.execfile(".\\src\\test\\resources\\hello.py");
}

Upvotes: 0

Vikas
Vikas

Reputation: 7185

I came across this error and the above solution did not work for me. We need to add jython-standalone.jar to python home not the extracted Lib folder.

p.setProperty("python.path", "PATH TO jython-standalone-2.7.0.jar");

Or

JAVA_OPTS="$JAVA_OPTS -Dpython.home=/PATH TO /jython-standalone-2.7.0.jar"

Hope this helps someone.

Upvotes: 0

zhao
zhao

Reputation: 1124

Using jython-standalone.jar works for me.

In Maven:https://mvnrepository.com/artifact/org.python/jython-standalone

pom.xml:

<dependency>
    <groupId>org.python</groupId>
    <artifactId>jython-standalone</artifactId>
    <version>2.7.1</version>
</dependency>

Upvotes: 18

Chandramohan KN
Chandramohan KN

Reputation: 54

Looks like the python path is referring to a default location. So you have two options to fix this. First is to copy the Jython library inside "C:\apache-tomcat-8.5.24\webapps\jython\WEB-INF\lib\Lib". In order to copy the jython library you need to unzip the contents of jython standalone jar in to this folder.

The other option is to set the python path to point to the location where the jython standalone jar is unzipped. The code looks something like this:

 PythonInterpreter interpreter = null;
    try{
            Properties p = new Properties();
            p.setProperty("python.path", "PATH OF JYTHON");
            p.setProperty("python.home", "PATH OF JYTHON");
            p.setProperty("python.prefix", "PATH OF JYTHON");
            PythonInterpreter.initialize(System.getProperties(), p, new String[] {});
        interpreter = new PythonInterpreter();
    }catch(Exception ex){
        log.error("Exception while creating python interpreter: "+ex.toString());
    }

Upvotes: 3

Related Questions