Odpowiedzi:
Jython: Python dla platformy Java - http://www.jython.org/index.html
Możesz łatwo wywoływać funkcje Pythona z kodu Java za pomocą Jythona. To jest tak długo, jak sam kod Pythona działa pod jythonem, tj. Nie używa niektórych rozszerzeń c, które nie są obsługiwane.
Jeśli to działa, z pewnością jest to najprostsze rozwiązanie, jakie możesz uzyskać. W przeciwnym razie możesz skorzystać org.python.util.PythonInterpreter
z nowej obsługi interpretera Java6.
Prosty przykład z góry mojej głowy - ale mam nadzieję, że powinien zadziałać: (brak sprawdzania błędów dla zwięzłości)
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);
Hej, myślałem, że podam swoją odpowiedź, mimo że jest późno. Myślę, że jest kilka ważnych rzeczy, które należy najpierw rozważyć, a mianowicie, jak silne chcesz mieć połączenie między Javą a Pythonem.
Po pierwsze, czy chcesz tylko wywoływać funkcje, czy faktycznie chcesz, aby kod Pythona zmieniał dane w obiektach Java? To jest bardzo ważne. Jeśli chcesz tylko wywołać jakiś kod Pythona z argumentami lub bez, to nie jest to zbyt trudne. Jeśli twoje argumenty są prymitywne, będzie to jeszcze łatwiejsze. Jeśli jednak chcesz mieć funkcje składowe klasy java implementujące w Pythonie, które zmieniają dane obiektu java, to nie jest to takie łatwe ani proste.
Po drugie, czy mówimy o cpythonie, czy też zrobi to jython? Powiedziałbym, że cpython jest tam, gdzie jest! Opowiadałbym się za tym, dlaczego Python jest taki kool! Mając tak wysokie abstrakcje, jednak w razie potrzeby dostęp do c, c ++. Wyobraź sobie, że możesz to mieć w Javie. To pytanie nie jest nawet warte pytania, czy jython jest w porządku, ponieważ i tak jest to łatwe.
Więc bawiłem się następującymi metodami i wymieniłem je od łatwych do trudnych:
Java na Jython
Zalety: banalnie proste. Mają rzeczywiste odniesienia do obiektów Java
Wady: brak CPythona, bardzo wolno!
Jython z javy jest tak łatwy, a jeśli to naprawdę wystarczy, to świetnie. Jednak jest bardzo powolny i nie ma cpythonu! Czy warto żyć bez cpythona, nie sądzę! Możesz łatwo mieć kod Pythona implementujący funkcje składowe dla obiektów Java.
Java na Jython na CPython przez Pyro
Pyro to zdalny moduł obiektowy dla Pythona. Masz jakiś obiekt na interpretatorze cpython i możesz wysłać mu obiekty, które są przesyłane przez serializację, a także może zwracać obiekty za pomocą tej metody. Zwróć uwagę, że jeśli wyślesz zserializowany obiekt Pythona z jythona, a następnie wywołasz funkcje, które zmieniają dane w jego elementach członkowskich, nie zobaczysz tych zmian w java. Musisz tylko pamiętać o odesłaniu żądanych danych z pyro. Myślę, że to najłatwiejszy sposób, aby dostać się do cpython! Nie potrzebujesz żadnego jni, jna, swig lub ... Nie musisz znać żadnego c ani c ++. kool co?
Zalety: Dostęp do cpython, nie tak trudny, jak następujące metody
Wady: nie można zmienić danych składowych obiektów Java bezpośrednio z Pythona. Jest nieco pośredni (jython jest pośrednikiem).
Java na C / C ++ przez JNI / JNA / SWIG do Pythona przez wbudowany interpreter (może przy użyciu bibliotek BOOST?)
OMG, ta metoda nie jest dla osób o słabym sercu. I mogę powiedzieć, że zajęło mi to bardzo dużo czasu, zanim udało mi się to osiągnąć przyzwoitą metodą. Głównym powodem, dla którego chciałbyś to zrobić, jest to, że możesz uruchomić kod cpython, który będzie miał pełną kontrolę nad obiektem Java. Przed podjęciem decyzji o spróbowaniu chleba java (który jest jak szympans) z pytonem (który jest jak koń), należy wziąć pod uwagę ważne kwestie. Po pierwsze, jeśli zawiesisz interpreter, który jest wyłączony dla twojego programu! I nie zaczynaj od kwestii współbieżności! Ponadto jest dużo kotła, wierzę, że znalazłem najlepszą konfigurację, aby zminimalizować ten kocioł, ale nadal jest! Jak więc się do tego zabrać: Weź pod uwagę, że C ++ jest twoim pośrednikiem, twoje obiekty to w rzeczywistości obiekty c ++! Dobrze, że już to wiesz. Po prostu napisz swój obiekt tak, jakby twój program był jak w cpp, a nie java, z danymi, do których chcesz uzyskać dostęp z obu światów. Następnie możesz użyć generatora opakowań o nazwie swig (http://www.swig.org/Doc1.3/Java.html ), aby udostępnić to java i skompilować bibliotekę dll, którą wywołujesz System.load (tutaj nazwa dll) w java. Najpierw zajmij się tym, a potem przejdź do najtrudniejszej części! Aby dostać się do Pythona, musisz osadzić interpreter. Po pierwsze proponuję robi kilka programów tłumacza hello czy ten samouczek Osadzanie Pythona w C / C . Kiedy już to zrobisz, pora zmusić konia i małpkę do tańca! Możesz wysłać obiekt C ++ do Pythona przez [boost] [3]. Wiem, że nie dałem ci ryby, powiedziałem tylko, gdzie ją znaleźć. Kilka wskazówek, na które należy zwrócić uwagę podczas kompilacji.
Podczas kompilacji przyspieszenia musisz skompilować bibliotekę współdzieloną. I musisz dołączyć i linkować do rzeczy, których potrzebujesz z jdk, tj. Jawt.lib, jvm.lib (będziesz również potrzebować klienta jvm.dll w swojej ścieżce podczas uruchamiania aplikacji), a także python27.lib lub cokolwiek i boost_python-vc100-mt-1_55.lib. Następnie dołącz Python / include, jdk / include, boost i używaj tylko bibliotek współdzielonych (dll), w przeciwnym razie boost ma kłopoty. I tak, w pełni wiem. Jest tak wiele sposobów, w jakie może się to zepsuć. Więc upewnij się, że wykonujesz każdą rzecz blok po bloku. Następnie złóż je razem.
Nie jest mądrze mieć kod Pythona w java. Zawiń swój kod w języku Python za pomocą platformy flask lub innej platformy internetowej, aby uczynić go mikrousługą. Spraw, aby Twój program java mógł wywoływać tę mikrousługę (np. Przez REST).
Uwierz mi, to jest o wiele proste i pozwoli Ci zaoszczędzić mnóstwo problemów. Kody są luźno powiązane, więc są skalowalne.
Zaktualizowano 24 marca 2020 r .: Zgodnie z komentarzem @ stx powyższe podejście nie nadaje się do masowego przesyłania danych między klientem a serwerem. Oto inne podejście, które poleciłem: Łączenie Pythona i Javy z Rustem (C / C ++ również ok). https://medium.com/@shmulikamar/https-medium-com-shmulikamar-connecting-python-and-java-with-rust-11c256a1dfb0
Tutaj biblioteka, która pozwala ci raz napisać skrypty Pythona i zdecydować, której metody integracji (Jython, CPython / PyPy przez Jep i Py4j) użyć w czasie wykonywania:
https://github.com/subes/invesdwin-context-python
Ponieważ każda metoda ma swoje zalety / wady, jak wyjaśniono w linku.
To zależy od tego, co masz na myśli przez funkcje Pythona? jeśli zostały napisane w cpythonie , nie możesz ich bezpośrednio wywołać, będziesz musiał użyć JNI , ale jeśli zostały napisane w Jythonie możesz je łatwo wywołać z javy, ponieważ jython ostatecznie generuje kod bajtowy java.
Teraz, kiedy mówię napisane w cpythonie lub jythonie, nie ma to większego sensu, ponieważ python to python i większość kodu będzie działać na obu implementacjach, chyba że używasz określonych bibliotek, które opierają się na cpythonie lub javie.
zobacz tutaj, jak używać interpretera Pythona w Javie.
GraalVM to dobry wybór. Zrobiłem połączenie Java + Javascript z GraalVM do projektowania mikrousług (Java z odzwierciedleniem Javascript). Niedawno dodali obsługę Pythona, spróbuję, szczególnie biorąc pod uwagę, jak duża stała się jego społeczność na przestrzeni lat.
Możesz wywołać dowolny język z javy przy użyciu natywnego interfejsu Java
Jython ma pewne ograniczenia:
Istnieje wiele różnic. Po pierwsze, programy w języku Jython nie mogą używać modułów rozszerzających CPython napisanych w języku C. Moduły te zwykle mają pliki z rozszerzeniami .so, .pyd lub .dll. Jeśli chcesz skorzystać z takiego modułu, powinieneś poszukać odpowiednika napisanego w czystym Pythonie lub Javie. Chociaż obsługa takich rozszerzeń jest technicznie wykonalna - IronPython to robi - nie ma takich planów w Jythonie.
Rozpowszechnianie moich skryptów w języku Python jako plików JAR w języku Jython?
możesz po prostu wywołać skrypty Pythona (lub skrypty bash lub Perl) z języka Java za pomocą środowiska uruchomieniowego lub ProcessBuilder i przekazać dane wyjściowe z powrotem do języka Java:
Uruchamianie skryptu powłoki bash w java
Uruchamianie wiersza poleceń w Javie
java runtime.getruntime () pobiera dane wyjściowe z wykonania programu wiersza poleceń
To daje całkiem dobry przegląd ciągu bieżącej opcji. Niektóre z nich są wymienione w innych odpowiedziach. Jython nie nadaje się do użytku, dopóki nie zdecydują się na wdrożenie Pythona 3.x, a wiele innych projektów pochodzi ze strony Pythona i chce mieć dostęp do javy. Ale jest jeszcze kilka opcji, aby nazwać coś, co nie zostało jeszcze nazwane: gRPC