running jython bytecode using java

心已入冬 提交于 2019-11-29 02:01:39

Here's what works for me:

test_p.py:

def foo():
  print 'test from Python'

TestJ.java:

import org.python.core.PyFrame;
import org.python.core.PyFunctionTable;
import org.python.util.PythonInterpreter;

public class TestJ
{
  public static void main(String[] args)
  {
    final PythonInterpreter interpreter = new PythonInterpreter();

    interpreter.exec("import sys");

    try
      {
        final Class<?> clazz = Class.forName("test_p$py");

        final java.lang.reflect.Constructor constructor
          = clazz.getConstructor(String.class);

        final PyFunctionTable module = (PyFunctionTable)constructor.newInstance("");

        final java.lang.reflect.Method method
          = clazz.getDeclaredMethod("foo$1",
                                    PyFrame.class,
                                    org.python.core.ThreadState.class);

        method.invoke(module,
                      (PyFrame)interpreter.eval("sys._getframe()").__tojava__(PyFrame.class),
                      org.python.core.Py.getThreadState());
      }
    catch (final ClassNotFoundException e)
      { e.printStackTrace(); }
    catch (final NoSuchMethodException e)
      { e.printStackTrace(); }
    catch (final InstantiationException e)
      { e.printStackTrace(); }
    catch (final IllegalAccessException e)
      { e.printStackTrace(); }
    catch (final java.lang.reflect.InvocationTargetException e)
      { e.printStackTrace(); }
  }
}

Compile test_p.py into test_p$py.class:

$JYTHON_HOME/jython $JYTHON_HOME/Lib/compileall.py .

Move test_p.py out of the way, to prove it's not being used:

mkdir hidden
mv test_p.py hidden/

Compile:

javac -cp $JYTHON_HOME/jython.jar TestJ.java

Test:

java -cp $JYTHON_HOME/jython.jar:. TestJ

Output:

test from Python

See FAQ - Embedding Jython.

Note that jythonc is no longer supported:

jythonc doesn't handle generators and is difficult to debug and improve. The current thinking is to add capabilites to jython itself to generate bytecode from py files and run those statically compiled items rather than jythonc's approach of making Java classes that work like the base Python code. The current thinking runs as follows:

  • Turn Python classes into Java classes without a Java interface or class using function annotations to specify the static Java type information
  • statically compile proxy classes for Python classes that extend Java classes
  • remove code from core that is only there to support jythonc

The example suggests special annotation for any method in a Python class that needs to be visible from Java:

class Simple(object):
  @java
  def __init__(self):

  @java(String, String)
  def firstWord(self, param):
    return param.split(' ')[0]

If your only concern is distributing your application without giving away the source, you might want to look at tools like cx_freeze and py2exe on Windows and py2app on Mac.

These tools have the ability to compile .py files to bytecode.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!