6

I wrote a Java example, the code is:

import org.python.core.PyObject;
import org.python.util.PythonInterpreter;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.util.List;

class JythonExample {

  public static void main(String args[]) throws ScriptException {
    listEngines();

    ScriptEngineManager mgr = new ScriptEngineManager();
    ScriptEngine pyEngine = mgr.getEngineByName("python");

    try {
      pyEngine.eval("print \"Python - Hello, world!\"");
    } catch (Exception ex) {
      ex.printStackTrace();
    }

    final PythonInterpreter interpreter = new PythonInterpreter();
    interpreter.exec("print \"Python - Hello, world!\"");

    PyObject result = interpreter.eval("2 + 3");
    System.out.println(result.toString());
  }

  public static void listEngines(){
    ScriptEngineManager mgr = new ScriptEngineManager();
    List<ScriptEngineFactory> factories =
        mgr.getEngineFactories();
    for (ScriptEngineFactory factory: factories) {
      System.out.println("ScriptEngineFactory Info");
      String engName = factory.getEngineName();
      String engVersion = factory.getEngineVersion();
      String langName = factory.getLanguageName();
      String langVersion = factory.getLanguageVersion();
      System.out.printf("\tScript Engine: %s (%s)\n",
          engName, engVersion);
      List<String> engNames = factory.getNames();
      for(String name: engNames) {
        System.out.printf("\tEngine Alias: %s\n", name);
      }
      System.out.printf("\tLanguage: %s (%s)\n",
          langName, langVersion);
    }
  }
}

In my pom.xml, if I use:

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

then I can run java -jar target/jython-example-1.0-SNAPSHOT.jar successfuly, by the way, I used maven-assembly-plugin to build a runnable jar.

if I use:

<dependency>
    <groupId>org.python</groupId>
    <artifactId>jython</artifactId>
    <version>2.7.0</version>
</dependency>

then when I run java -jar target/jython-example-1.0-SNAPSHOT.jar, I'll always get the following error:

ScriptEngineFactory Info
    Script Engine: jython (2.7.0)
    Engine Alias: python
    Engine Alias: jython
    Language: python (2.7)
ScriptEngineFactory Info
    Script Engine: Oracle Nashorn (1.8.0_31)
    Engine Alias: nashorn
    Engine Alias: Nashorn
    Engine Alias: js
    Engine Alias: JS
    Engine Alias: JavaScript
    Engine Alias: javascript
    Engine Alias: ECMAScript
    Engine Alias: ecmascript
    Language: ECMAScript (ECMA - 262 Edition 5.1)
java.lang.NullPointerException
    at me.soulmachine.JythonExample.main(JythonExample.java:21)
Exception in thread "main" ImportError: Cannot import site module and its dependencies: No module named site
Determine if the following attributes are correct:
  * sys.path: ['/home/programmer/src/github/JythonExample/JythonExample/target/Lib', '__classpath__', '__pyclasspath__/']
    This attribute might be including the wrong directories, such as from CPython
  * sys.prefix: /home/programmer/src/github/JythonExample/JythonExample/target
    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

It seems the pyEngine is null.

So I wonder what's the difference between jython-standalone-2.7.0.jar and jython-2.7.0.jar

soulmachine
  • 3,917
  • 4
  • 46
  • 56
  • The difference is that the standalone jar does not use the cache and so (in theory) can be deployed to end users. That is consistent with your code being unable to import the site modules. -- Off topic - Can you provide more information on building runnable jars. I am having issues with it in 2.7 – Paul Smith May 06 '15 at 09:28

2 Answers2

7

One problem I've just discovered with the same error is that the maven build 2.7.0 does not include the lib folder. This is probably a build error for the release build. I had to move up the b2 build which does properly include the lib folder in the supplied jar.

Problem maven 2.7.0 jar:
<dependency> <groupId>org.python</groupId> <artifactId>jython-standalone</artifactId> <version>2.7.0</version> </dependency>

Working maven 2.7.1b2 that includes the lib folder:
<dependency> <groupId>org.python</groupId> <artifactId>jython-standalone</artifactId> <version>2.7.1b2</version> </dependency>

NOTE: If you download the jar directly from the Jython site it does correctly include the lib folder. It's just the maven repository version.

Tim Cederquist
  • 191
  • 3
  • 6
3

I believe the main difference causing your issue is that the jython-standalone jar provides Lib/ (which contains site.py) while the jython jar does not.

https://github.com/scijava/jython-shaded gives a more in-depth description of the issue, as well as other issues, and provides an alternative jar to get around some issues noted in the description.

I don't have experience with scijava:jython-shaded, but I substituted it into your pom (for my setup I also had to change jdk.version to 1.7 and to JythonExample) and your example runs.

Phil Brown
  • 361
  • 1
  • 7