2010-04-06 19 views
9

Parece que me falta algo.ejecutando bytecode jython usando java

Al usar Jython para ejecutar mi código de Python en Java, se generan archivos de código de bytes de Java (test.py -> [email protected]).

¿Puedo ejecutar estas clases directamente usando java?

En otras palabras, quiero hacer esto:

$ java [email protected] [additional cp args] 

trabajo.

La intención: escribir el código de Python y no tener que regalar el código fuente.

Respuesta

3

Ver FAQ - Embedding Jython.

Tenga en cuenta que es jythoncno longer supported:

jythonc no maneja generadores y es difícil de depurar y mejorar. El pensamiento actual es agregar capabilites a jython para generar bytecode a partir de archivos py y ejecutar los elementos compilados estáticamente en lugar del enfoque de jythonc de crear clases Java que funcionen como el código base de Python. El pensamiento actual es la siguiente:

  • clases Encienda Python en clases Java sin una interfaz Java o clase utilizando anotaciones de función para especificar la información de tipo Java estática
  • estáticamente compilar clases de proxy para las clases de Python que se extienden las clases de Java
  • código quitar desde el núcleo que sólo está allí para apoyar jythonc

El ejemplo sugiere anotación especial para cualquier método en una clase Python que necesita ser vis Ible de Java:

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

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

Si su única preocupación es la distribución de su aplicación sin revelar la fuente, es posible que desee ver en herramientas como cx_freeze y py2exe en Windows y en Mac py2app.

Estas herramientas tienen la capacidad de compilar archivos .py en bytecode.

+0

El compilador pypy probablemente sea una mejor apuesta desde una perspectiva de ofuscación. Desafortunadamente, es muy difícil de usar. – Antimony

4

Aquí es lo que funciona para mí:

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(); } 
    } 
} 

Compilar test_p.py en test_p $ py.class :

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

Mover test_p.py fuera del camino, para demostrar que no se está utilizando:

mkdir hidden 
mv test_p.py hidden/ 

Compilar:

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

prueba:

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

Salida:

test from Python