Running Jython Bytecode Using Java
It looks like I'm missing something. When using Jython to run my Python code in Java, Java bytecode files are generated (test.py -> test@py.class). Can I run these classes direc
Solution 1:
Here's what works for me:
test_p.py:
deffoo():
print'test from Python'
TestJ.java:
import org.python.core.PyFrame;
import org.python.core.PyFunctionTable;
import org.python.util.PythonInterpreter;
publicclassTestJ
{
publicstaticvoidmain(String[] args)
{
finalPythonInterpreterinterpreter=newPythonInterpreter();
interpreter.exec("import sys");
try
{
final Class<?> clazz = Class.forName("test_p$py");
final java.lang.reflect.Constructorconstructor= clazz.getConstructor(String.class);
finalPyFunctionTablemodule= (PyFunctionTable)constructor.newInstance("");
final java.lang.reflect.Methodmethod= 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
Solution 2:
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:
classSimple(object):@javadef__init__(self):
@java(String, String)
deffirstWord(self, param):
return param.split(' ')[0]
Post a Comment for "Running Jython Bytecode Using Java"