запуск байт-кода jython с использованием Java - PullRequest
10 голосов
/ 06 апреля 2010

Похоже, я что-то упустил.

При использовании Jython для запуска моего кода Python в Java создаются файлы байт-кода Java (test.py -> test@py.class).

Могу ли я запустить эти классы напрямую, используя Java?

Другими словами, я хочу сделать это:

$ java test@py [additional cp args]

работа.

Цель: написание кода на Python и отсутствие необходимости выдавать исходный код.

Ответы [ 3 ]

4 голосов
/ 11 апреля 2013

Вот что у меня работает:

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

Скомпилируйте test_p.py в test_p $ py.class:

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

Уберите test_p.py с пути, чтобы доказать, что он не используется:

mkdir hidden
mv test_p.py hidden/

Компиляция:

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

Тест:

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

Выход:

test from Python
3 голосов
/ 06 апреля 2010

См. FAQ - Встраивание Jython .

Обратите внимание, что jythonc больше не поддерживается :

jythonc не обрабатывает генераторы и его сложно отлаживать и улучшать. В настоящее время мы думаем о добавлении возможностей в сам jython для генерации байт-кода из py-файлов и запуска этих статически скомпилированных элементов, а не в подходе jythonc по созданию классов Java, которые работают как базовый код Python. Текущее мышление работает следующим образом:

  • Превращение классов Python в классы Java без интерфейса или класса Java с использованием аннотаций функций для указания статической информации о типе Java
  • статически скомпилированные прокси-классы для классов Python, расширяющих классы Java
  • удалить код из ядра, которое существует только для поддержки jythonc

В примере предлагается специальная аннотация для любого метода в классе Python, который должен быть виден из Java:

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

  @java(String, String)
  def firstWord(self, param):
    return param.split(' ')[0]
0 голосов
/ 06 апреля 2010

Если ваша единственная задача - распространение вашего приложения без предоставления источника, вы можете посмотреть на такие инструменты, как cx_freeze и py2exe в Windows и py2app на Mac.

Эти инструменты имеют возможность компилировать .py файлы в байт-код.

...