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.xml
is 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
initializationI 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?
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>
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());
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With