2010-04-06 10 views
9

Il semble qu'il me manque quelque chose. Lorsque j'utilise Jython pour exécuter mon code Python en Java, des fichiers de bytecode Java sont générés (test.py -> [email protected]). Est-ce que je peux exécuter ces classes directement en utilisant java?en cours d'exécution Jython bytecode en utilisant Java

En d'autres termes, je veux faire ceci:

$ java [email protected] [additional cp args] 
travail

.

L'intention: écrire du code Python et ne pas avoir à donner de code source.

Répondre

3

Voir FAQ - Embedding Jython.

Notez que jythonc est no longer supported:

jythonc ne gère pas les générateurs et il est difficile de déboguer et d'améliorer. La pensée actuelle est d'ajouter des capacités à jython lui-même pour générer le bytecode à partir de fichiers py et exécuter ces éléments statiquement compilés plutôt que l'approche de jythonc de faire des classes Java qui fonctionnent comme le code Python de base. La réflexion actuelle est la suivante:

  • tour classes Python dans les classes Java sans interface Java ou classe en utilisant des annotations de fonction pour spécifier les informations de type Java statique
  • compiler statiquement classes proxy pour les classes Python qui étendent les classes Java
  • supprimer le code de base qui est seulement là pour soutenir jythonc

L'exemple suggère annotation spéciale pour une méthode d'une classe de python qui doit être vis Ible de Java:

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

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

Si votre seule préoccupation est la distribution de votre demande sans donner la source, vous pouvez regarder des outils comme cx_freeze et py2exe sous Windows et sur Mac py2app.

Ces outils permettent de compiler des fichiers .py en bytecode.

+0

Le compilateur pypy est probablement un meilleur pari d'un point de vue obfuscation. Malheureusement, c'est très difficile à utiliser. – Antimony

4

est ici ce qui fonctionne pour moi:

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

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

Déplacer test_p.py de la route, pour le prouver n'est pas utilisé:

mkdir hidden 
mv test_p.py hidden/ 

Compile:

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

Test:

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

Sortie:

test from Python