Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 577
Christine VACHER Avatar asked Jan 11 '18 21:01

Christine VACHER


Video Answer


2 Answers

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>
like image 143
zhao Avatar answered Sep 23 '22 00:09

zhao


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());
    }
like image 20
Chandramohan KN Avatar answered Sep 22 '22 00:09

Chandramohan KN