Как вызвать Java-объекты и функции из CPython? - PullRequest
11 голосов
/ 13 января 2009

У меня есть программа на Python, которая работает на реализации CPython, и внутри нее я должен вызвать функцию, определенную в Java-программе. Как я могу это сделать?

Было бы неплохо также использовать некоторые java-объекты.

Jython не вариант. Я должен запустить часть Python в CPython.

Ответы [ 6 ]

13 голосов
/ 25 сентября 2010

Извините за воскрешение темы, но я думаю, что у меня есть лучший ответ: -)

Вы также можете использовать Py4J , который состоит из двух частей: библиотеки, работающей на CPython (или любого интерпретатора Python в этом отношении), и библиотеки, работающей на виртуальной машине Java, которую вы хотите вызвать.

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

>>> from py4j.java_gateway import JavaGateway
>>> gateway = JavaGateway()                        # connect to the JVM
>>> java_object = gateway.jvm.mypackage.MyClass()  # invoke constructor
>>> other_object = java_object.doThat()
>>> other_object.doThis(1,'abc')
>>> gateway.jvm.java.lang.System.out.println('Hello World!') # call a static method

Связь осуществляется через сокеты вместо JNI.

Отказ от ответственности: я являюсь автором Py4J

9 голосов
/ 13 января 2009

Самое простое, что нужно сделать, это

  1. Напишите тривиальный CLI для вашей Java-функции. (Этого нет, поэтому я предполагаю, что вы на самом деле имеете в виду метод-функцию класса Java.)

    public class ExposeAMethod {
        public static void main( String args[] ) {
             TheClassToExpose  x = new TheClassToExpose();
            x.theFunction();
        }
    }
    
  2. Скомпилируйте и скомпилируйте исполняемый файл JAR с этим в качестве точки входа. Назови это ExposeAMethod.jar

  3. Вызовите это из команды, созданной подпроцессом.

    import subprocess
    p = subprocess.Popen("java -jar ExposeAMethod.jar", shell=True)
    sts = os.waitpid(p.pid, 0)
    

Это минимум. И это действительно не так много. Я считаю 6 строк Java, 3 строки Python, и вы работаете.

Если вы хотите передать аргументы в этот конструктор класса Java или функцию метода, вам придется написать еще несколько строк кода. У вас есть два варианта.

  • Прочитайте аргументы из stdin, запишите результаты в stdout. Это относительно просто и очень хорошо работает.

  • Разобрать аргументы как параметры командной строки для Java, записать результаты в стандартный вывод. Это немного сложнее, но обобщает очень хорошо. Бонус в том, что теперь у вас есть полезная Java-программа для командной строки, которую вы можете использовать повторно.

7 голосов
/ 14 января 2009

Если вы не хотите идти, напишите свой собственный маршрут JNI / C.

Другой вариант - использовать jpype, который я всегда использую для доступа к базам данных Oracle, потому что установка драйверов oracle c на ПК - это pita. Вы можете делать такие вещи, как (из документов):

 from jpype import * 
 startJVM("d:/tools/j2sdk/jre/bin/client/jvm.dll", "-ea") # or path to your jvm
 java.lang.System.out.println("hello world") 
 shutdownJVM()

Он давно не обновлялся, и документации немного, но он работает достаточно хорошо.

1 голос
/ 16 июня 2014

Посмотрите на наш проект python-javabridge . Это оболочка Python для JNI, интенсивно используемая CellProfiler . Он предлагает как низкоуровневый доступ к JNI, так и высокоуровневый доступ к объектам Java на основе отражений.

1 голос
/ 13 января 2009

Вам нужно будет создать расширение Python C, которое будет встраивать Java - на основе чего-то вроде http://www.javaworld.com/javaworld/jw-05-2001/jw-0511-legacy.html, иначе вам придется запустить Java в отдельном подпроцессе.

1 голос
/ 13 января 2009

Я не знаю, для Python, но в прошлый раз мне пришлось вызывать Java из приложения C (служба NT), мне пришлось загрузить jvm.dll. Посмотрите документацию JNI.

Также звоните всегда звоните

os.system("java com.myapp.MyClass") 

, если вас не беспокоит производительность.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...