回答:
Jython:Python for the Java Platform- http://www.jython.org/index.html
Jythonを使用すると、JavaコードからPython関数を簡単に呼び出すことができます。これは、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コードを呼び出したいだけなら、それはそれほど難しくありません。引数がプリミティブである場合は、さらに簡単になります。ただし、PythonでJavaクラスにメンバー関数を実装させて、Javaオブジェクトのデータを変更する場合は、これはそれほど簡単ではなく、簡単でもありません。
第二に、私たちはcpythonを話しているのですか、それともjythonがしますか?私はcpythonがその場所にあると言います!私はこれがpythonがとてもクールな理由だと主張します!ただし、このように高度な抽象化を行うと、必要に応じてc、c ++にアクセスできます。あなたがJavaでそれを持つことができるかどうか想像してみてください。この質問は、とにかく簡単なので、jythonが大丈夫かどうかを尋ねる価値はありません。
だから私は以下の方法で遊んで、それらを簡単なものから難しいものまでリストしました:
JavaからJython
利点:簡単です。Javaオブジェクトへの実際の参照がある
短所: CPythonがなく、非常に遅い!
JavaのJythonはとても簡単です。これで本当に十分なら、素晴らしいです。しかし、それは非常に遅く、cpythonはありません!私はそうは思わないcpythonなしで生活する価値がある人生です!あなたはあなたのJavaオブジェクトのためにあなたのメンバー関数を実装するPythonコードを簡単に持つことができます。
Pyroを介したJavaからJython、CPythonへ
Pyroは、Pythonのリモートオブジェクトモジュールです。cpythonインタープリターにいくつかのオブジェクトがあり、シリアライゼーションを介して転送されるオブジェクトを送信したり、このメソッドを介してオブジェクトを返すこともできます。jythonからシリアル化されたpythonオブジェクトを送信し、そのメンバーのデータを変更するいくつかの関数を呼び出した場合、Javaでそれらの変更が表示されないことに注意してください。あなたはpyroから欲しいデータを送り返すことを覚えておく必要があるだけです。これはcpythonにアクセスする最も簡単な方法だと思います!jni、jna、swig、...は必要ありません。c、またはc ++を知っている必要はありません。ねえ?
利点:次の方法ほど難しくないcpythonへのアクセス
欠点: Pythonから直接Javaオブジェクトのメンバーデータを変更することはできません。多少間接的です(jythonは中間者です)。
JavaからC / C ++へ、JNI / JNA / SWIGからPythonへ、埋め込みインタープリターを介して(おそらくBOOSTライブラリを使用して?)
OMGこの方法は、気の弱い人には向いていません。まともな方法でこれを実現するのに非常に時間がかかったと私は言うことができます。これを行う主な理由は、Javaオブジェクトを完全に制御するcpythonコードを実行できるようにするためです。python(馬のようなもの)でjava(チンパンジーのようなもの)を試してみる前に、考慮すべき主要な重要事項があります。まず、インタープリターをクラッシュさせると、プログラムは完全に消灯します。そして、同時実行の問題から始めないでください!さらに、ボイラーの割り当ての割り当てがあります。このボイラーを最小限に抑えるための最良の構成を見つけたと思いますが、それでも割り当てです。だから、これをどうやってやるか:C ++があなたの仲介者だと考えてください、あなたのオブジェクトは実際にはc ++オブジェクトです!あなたが今それを知っているのは良いことです。あなたのプログラムをJavaではなくcppのように書くだけで、両方の世界からアクセスしたいデータ。次に、swigと呼ばれるラッパージェネレーターを使用できます(http://www.swig.org/Doc1.3/Java.html)これをJavaにアクセスできるようにし、JavaでSystem.load(dll name here)を呼び出すDLLをコンパイルします。最初にこれを機能させてから、難しい部分に進んでください!Pythonにアクセスするには、インタープリターを組み込む必要があります。最初に、いくつかのhelloインタープリタープログラムまたはこのチュートリアルC / CへのPythonの埋め込みを行うことをお勧めします。それがうまくいったら、馬と猿を踊らせる時です![boost] [3]を介してPythonにc ++オブジェクトを送信できます。私はあなたに魚を与えなかったのを知っています、ただ魚を見つける場所をあなたに話しました。コンパイル時にこれについて注意すべきいくつかのポインタ。
boostをコンパイルするときは、共有ライブラリをコンパイルする必要があります。そして、jdkから必要なもの、つまりjawt.lib、jvm.libを含めてリンクする必要があります(アプリケーションを起動するときに、パスにクライアントjvm.dllも必要です)python27.libまたは何でも、boost_python-vc100-mt-1_55.lib。次に、Python / include、jdk / include、boostを含め、共有ライブラリ(dll)のみを使用します。そうしないと、boostに問題があります。ええ、私は完全に知っています。これが酸っぱいことができる方法はたくさんあります。したがって、ブロックごとに各処理を実行するようにしてください。その後、それらを一緒に置きます。
Javaの内部にPythonコードを置くのは賢明ではありません。Pythonコードをフラスコまたはその他のWebフレームワークでラップして、マイクロサービスとして作成します。Javaプログラムがこのマイクロサービスを(たとえばREST経由で)呼び出せるようにします。
私を信じて、これは非常に簡単であり、あなたにたくさんの問題を救います。また、コードは疎結合されているため、スケーラブルです。
2020年3月24日に更新:@stxのコメントによると、上記のアプローチはクライアントとサーバー間の大量のデータ転送には適していません。ここに私が推奨する別のアプローチがあります:PythonとJavaをRustで接続します(C / C ++もOK)。 https://medium.com/@shmulikamar/https-medium-com-shmulikamar-connecting-python-and-java-with-rust-11c256a1dfb0
ここでは、Pythonスクリプトを1回記述し、実行時に使用する統合方法(Jython、JepおよびPy4jを介したCPython / PyPy)を決定できるライブラリを示します。
https://github.com/subes/invesdwin-context-python
リンクで説明されているように、各メソッドには独自の利点/欠点があります。
それはあなたがPython関数によって何を意味するかに依存しますか?それらがcpythonで書かれている場合は直接呼び出すことはできませんが、JNIを使用する必要がありますが、jythonが最終的にJavaバイトコードを生成するため、Jythonで書かれている場合はJavaから簡単に呼び出すことができます。
今私がcpythonまたはjythonで書かれていると言っても、pythonはpythonであり、cpythonまたはjavaに依存する特定のライブラリを使用しない限り、ほとんどのコードは両方の実装で実行されます。
JavaでPythonインタープリターを使用する方法については、こちらをご覧ください。
Java Native Interfaceを使用してJavaから任意の言語を呼び出すことができます
Jythonにはいくつかの制限があります。
いくつかの違いがあります。まず、JythonプログラムはCで記述されたCPython拡張モジュールを使用できません。これらのモジュールには通常、拡張子が.so、.pyd、または.dllのファイルがあります。このようなモジュールを使用する場合は、純粋なPythonまたはJavaで記述された同等のモジュールを探す必要があります。そのような拡張機能をサポートすることは技術的に実現可能ですが-IronPythonはそうです-Jythonではそうする予定はありません。
JythonでPythonスクリプトをJARファイルとして配布していますか?
RuntimeまたはProcessBuilderを使用してJavaからPythonスクリプト(またはbashまたはPerlスクリプト)を呼び出し、Javaに出力を返すだけです。