Ответы:
Jython: Python для платформы Java - http://www.jython.org/index.html
Вы можете легко вызывать функции Python из кода Java с помощью Jython. Это до тех пор, пока ваш код Python работает под jython, т.е. не использует некоторые c-расширения, которые не поддерживаются.
Если это сработает для вас, это, безусловно, самое простое решение, которое вы можете получить. В противном случае вы можете использовать org.python.util.PythonInterpreter
новую поддержку интерпретатора Java6.
Простой пример из моей головы - но я надеюсь, он сработает: (для краткости проверка ошибок не выполняется)
PythonInterpreter interpreter = new PythonInterpreter();
interpreter.exec("import sys\nsys.path.append('pathToModules if they are not there by default')\nimport yourModule");
// execute a function that takes a string and returns a string
PyObject someFunc = interpreter.get("funcName");
PyObject result = someFunc.__call__(new PyString("Test!"));
String realResult = (String) result.__tojava__(String.class);
Эй, я думал, что введу свой ответ на этот вопрос, хотя уже поздно. Я думаю, что есть несколько важных моментов, которые следует учитывать в первую очередь, учитывая, насколько сильной вы хотите иметь связь между java и python.
Во-первых, вы хотите вызывать только функции или действительно хотите, чтобы код Python изменял данные в ваших java-объектах? Это очень важно. Если вы хотите вызвать код Python с аргументами или без них, это не очень сложно. Если ваши аргументы примитивны, это еще более упрощает задачу. Однако, если вы хотите, чтобы java-класс реализовал функции-члены в python, которые изменяют данные java-объекта, то это не так просто и прямо.
Во-вторых , мы говорим о cpython или подойдет jython? Я бы сказал, что cpython - это то, что вам нужно! Я бы сказал, что именно поэтому питон такой крутой! Имея такие высокие абстракции, при необходимости, доступ к c, c ++. Представьте, если бы это было в java. Этот вопрос даже не стоит задавать, подходит ли jython, потому что тогда это все равно легко.
Итак, я поиграл со следующими методами и перечислил их от простого к сложному:
Java в Jython
Преимущества: Тривиально просто. Имеются актуальные ссылки на объекты Java
Недостатки: нет CPython, очень медленно!
Jython из java настолько прост, и если этого действительно достаточно, то отлично. Однако это очень медленно и без cpython! Стоит ли жить без cpython, я так не думаю! Вы можете легко получить код Python, реализующий ваши функции-члены для Java-объектов.
Из Java в Jython в CPython через Pyro
Pyro - это модуль удаленного объекта для Python. У вас есть объект в интерпретаторе cpython, и вы можете отправлять ему объекты, которые передаются через сериализацию, а также он может возвращать объекты через этот метод. Обратите внимание: если вы отправляете сериализованный объект python из jython, а затем вызываете некоторые функции, которые изменяют данные в его элементах, вы не увидите этих изменений в java. Вам просто нужно не забыть отправить обратно те данные, которые вы хотите от пиротехники. Я считаю, что это самый простой способ попасть на cpython! Вам не нужны ни jni, ни jna, ни swig, ни .... Вам не нужно знать ни c, ни c ++. круто, да?
Преимущества: доступ к cpython, не такой сложный, как следующие методы
Недостатки: невозможно изменить данные членов объектов Java непосредственно из Python. Отчасти косвенно (jython - средний человек).
Из Java в C / C ++ через JNI / JNA / SWIG в Python через встроенный интерпретатор (возможно, с использованием библиотек BOOST?)
Боже мой, этот метод не для слабонервных. И я могу вам сказать, что мне потребовалось очень много времени, чтобы добиться этого приличным методом. Основная причина, по которой вы хотели бы это сделать, заключается в том, чтобы вы могли запускать код cpython, который полностью контролирует ваш объект java. Есть несколько важных моментов, которые следует учитывать, прежде чем принимать решение об использовании java (который похож на шимпанзе) с питоном (который похож на лошадь). Во-первых, если вы сломаете интерпретатор, это отключит вашу программу! И не заставляйте меня начинать с вопросов параллелизма! Кроме того, есть выделенный участок котла, я считаю, что нашел лучшую конфигурацию, чтобы минимизировать этот котел, но все же он выделен! Итак, как это сделать: считайте, что C ++ - ваш посредник, а ваши объекты на самом деле являются объектами C ++! Хорошо, что ты это знаешь сейчас. Просто напишите свой объект, как если бы ваша программа как в cpp, а не в java, с данными, к которым вы хотите получить доступ из обоих миров. Затем вы можете использовать генератор оболочки под названием swig (http://www.swig.org/Doc1.3/Java.html ), чтобы сделать это доступным для java и скомпилировать dll, которую вы вызываете System.load (имя dll здесь) в java. Сначала сделайте это, а затем переходите к самому сложному! Чтобы добраться до Python, вам нужно встроить интерпретатор. Во - первых , я предлагаю делать некоторые программы интерпретатора привет или это учебник Встраивание питона в C / C . Как только вы это сделаете, самое время заставить лошадь и обезьяну танцевать! Вы можете отправить объект C ++ в Python через [boost] [3]. Я знаю, что не давал вам рыбу, я просто сказал вам, где найти рыбу. Некоторые указатели, которые следует учитывать при компиляции.
Когда вы компилируете boost, вам нужно будет скомпилировать общую библиотеку. И вам нужно включить и связать нужные вам материалы из jdk, например jawt.lib, jvm.lib (вам также понадобится клиент jvm.dll на вашем пути при запуске приложения), а также python27.lib или что угодно и boost_python-vc100-mt-1_55.lib. Затем включите Python / include, jdk / include, boost и используйте только общие библиотеки (dll), иначе boost будет слезливым. И да, я знаю. Есть очень много способов, по которым это может испортиться. Поэтому убедитесь, что вы выполняете каждую вещь блок за блоком. Затем соедините их.
Неумно иметь код Python внутри java. Оберните свой код Python во флягу или другую веб-платформу, чтобы сделать его микросервисом. Сделайте вашу Java-программу способной вызывать этот микросервис (например, через REST).
Поверьте, это очень просто и избавит вас от множества проблем. Коды слабо связаны, поэтому их можно масштабировать.
Обновлено 24 марта 2020 г .: Согласно комментарию @stx, вышеуказанный подход не подходит для массовой передачи данных между клиентом и сервером. Вот еще один подход, который я рекомендовал: соединение Python и Java с Rust (C / C ++ тоже в порядке). https://medium.com/@shmulikamar/https-medium-com-shmulikamar-connecting-python-and-java-with-rust-11c256a1dfb0
Вот библиотека, которая позволяет вам один раз написать ваши скрипты на Python и решить, какой метод интеграции (Jython, CPython / PyPy через Jep и Py4j) использовать во время выполнения:
https://github.com/subes/invesdwin-context-python
Поскольку у каждого метода есть свои преимущества / недостатки, как описано в ссылке.
Это зависит от того, что вы подразумеваете под функциями Python? если они были написаны на cpython, вы не можете напрямую вызывать их, вам придется использовать JNI , но если они были написаны на Jython, вы можете легко вызвать их из java, поскольку jython в конечном итоге генерирует байтовый код java.
Теперь, когда я говорю, что написано на cpython или jython, это не имеет особого смысла, потому что python - это python, и большая часть кода будет работать в обеих реализациях, если вы не используете определенные библиотеки, которые полагаются на cpython или java.
GraalVM - хороший выбор. Я сделал комбинацию Java + Javascript с GraalVM для дизайна микросервисов (Java с отражением Javascript). Недавно они добавили поддержку python, я бы попробовал, особенно с учетом того, насколько большим стало его сообщество за эти годы.
Вы можете вызывать любой язык из Java, используя собственный интерфейс Java
У Jython есть некоторые ограничения:
Есть ряд отличий. Во-первых, программы Jython не могут использовать модули расширения CPython, написанные на C. Эти модули обычно имеют файлы с расширением .so, .pyd или .dll. Если вы хотите использовать такой модуль, вам следует поискать эквивалент, написанный на чистом Python или Java. Хотя технически возможно поддерживать такие расширения - IronPython делает это - в Jython это не планируется.
Распространять мои сценарии Python в виде файлов JAR с помощью Jython?
вы можете просто вызвать скрипты Python (или скрипты bash или Perl) из Java с помощью Runtime или ProcessBuilder и передать вывод обратно в Java:
Запуск сценария оболочки bash на java
Запуск командной строки в Java
java runtime.getruntime () получение вывода от выполнения программы командной строки
Это дает неплохой обзор текущих опций. Некоторые из них указаны в других ответах. Jython нельзя использовать, пока они не решат реализовать Python 3.x, а многие другие проекты создаются на стороне Python и хотят получить доступ к java. Но есть еще несколько вариантов, чтобы назвать то, что еще не было названо: gRPC