2010-04-06 9 views
9

Es sieht aus wie ich etwas vermisse.running jython bytecode mit java

Wenn ich Jython verwende, um meinen Python-Code in Java auszuführen, werden Java-Bytecode-Dateien erzeugt (test.py -> [email protected]).

Kann ich diese Klassen direkt mit Java ausführen?

Mit anderen Worten, ich möchte, dies machen:

$ java [email protected] [additional cp args] 

Arbeit.

Die Absicht: Python-Code schreiben und Quellcode nicht verschenken.

Antwort

3

Siehe FAQ - Embedding Jython.

Beachten Sie, dass jythonc ist no longer supported:

jythonc nicht behandelt Generatoren und ist schwer zu debuggen und verbessern. Die derzeitige Denkweise besteht darin, jython selbst Fähigkeiten hinzuzufügen, Bytecode aus py-Dateien zu generieren und diese statisch kompilierten Elemente auszuführen, anstatt jythoncs Ansatz, Java-Klassen zu erstellen, die wie der Basis-Python-Code funktionieren. Die derzeitigen Überlegungen laufen wie folgt ab:

  • Schalten Python-Klassen in Java-Klassen ohne eine Java-Schnittstelle oder Klasse Anmerkungen über die Funktion der statische Java Typinformation
  • statisch Proxy angeben Klassen für Python-Klassen erstellen, die Java-Klassen erweitern
  • Entfernen Code aus Kern, der nur dort zu unterstützen jythonc

Das Beispiel für jede Methode in einer Python-Klasse besondere Anmerkung deutet darauf hin, dass vis sein muss IVK von Java:

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

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

Wenn Ihre einzige Sorge ist Ihre Anwendung zu verteilen, ohne die Quelle verlosen, könnten Sie bei Tools wie cx_freeze und py2exe unter Windows und py2app auf Mac suchen.

Diese Tools haben die Fähigkeit, .py-Dateien in Bytecode zu kompilieren.

+0

Der Pypy-Compiler ist wahrscheinlich eine bessere Wette aus einer Verschleierungsperspektive. Leider ist es sehr schwer zu benutzen. – Antimony

4

Hier ist, was für mich funktioniert:

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 in test_p $ py.class :

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

Move test_p.py aus dem Weg, es zu beweisen, nicht verwendet werden:

mkdir hidden 
mv test_p.py hidden/ 

Compile:

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

Test:

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

Ausgang:

test from Python