web-dev-qa-db-ja.com

JavaからPythonを呼び出す

PythonからJavaを呼び出す最良の方法は何ですか? (jythonとRPCは私にとって選択肢ではありません)。

JCCについて聞いたことがあります: http://pypi.python.org/pypi/JCC/1.9 Java C++/Pythonからただし、これには可能な呼び出しをすべてコンパイルする必要があります。私は別の解決策を好むでしょう。

JPypeについて聞いたことがあります: http://jpype.sourceforge.net/ チュートリアル: http:// www.slideshare.net/onyame/mixing-python-and-Java

import jpype 
jpype.startJVM(path to jvm.dll, "-ea") 
javaPackage = jpype.JPackage("JavaPackageName") 
javaClass = javaPackage.JavaClassName 
javaObject = javaClass() 
javaObject.JavaMethodName() 
jpype.shutdownJVM() 

これは私が必要なもののように見えます。ただし、最後のリリースは2009年1月のもので、JPypeのコンパイルに失敗している人がいます。

JPypeは死んだプロジェクトですか?

他の選択肢はありますか?

よろしく、デビッド

114

この問題の要約は次のとおりです。PythonからJavaを呼び出す5つの方法

http://baojie.org/blog/2014/06/16/call-Java-from-python/cached

簡単な答え:Jpypeは非常にうまく機能し、多くのプロジェクト(python-boilerpipeなど)で実証されていますが、PyjniusはJPypeよりも高速でシンプルです

Pyjnius/Jnius、JCC、javabridge、Jpype、Py4jを試しました。

Py4jを使用するのは少し難しいです。ゲートウェイを開始する必要があるため、脆弱性の別のレイヤーが追加されます。

42
Jie Bao

Py4J を使用することもできます。フロントページと多くのドキュメントに例がありますが、本質的には、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

Jythonとは対照的に、Py4Jの一部はPython VMで実行されるため、Pythonの最新バージョンでは常に「最新」です。 Jythonでうまく動作しないライブラリ(lxmlなど)を使用します。他の部分は、呼び出したいJava VMで実行されます。

通信はJNIではなくソケットを介して行われ、Py4Jには独自のプロトコルがあります(特定のケースを最適化するため、メモリを管理するためなど)。

免責事項:私はPy4Jの著者です

127
Barthelemy

ピニニウス。

ドキュメント: http://pyjnius.readthedocs.org/en/latest/

Github: https://github.com/kivy/pyjnius

Githubページから:

JNIを使​​用してPythonクラスとしてJavaクラスにアクセスするPythonモジュール。

PyJNIusは「進行中の作業」です。

簡単な概要

>>> from jnius import autoclass
>>> autoclass('Java.lang.System').out.println('Hello world') Hello world

>>> Stack = autoclass('Java.util.Stack')
>>> stack = Stack()
>>> stack.Push('hello')
>>> stack.Push('world')
>>> print stack.pop() world
>>> print stack.pop() hello
17
gdw2

私はOSX 10.10.2を使用しており、JPypeの使用に成功しました。

Jniusでインストールの問題に遭遇しました( 他の人もいます )、Javabridgeをインストールしましたが、使用しようとすると謎のエラーが発生しました。PyJ4には、Java最初に、JCCはインストールしません。最後に、JPypeは機能しました。 Githubには JPypeのメンテナンスフォーク があります。 (a)適切にインストールされ、(b)Java配列をnumpy配列(np_arr = Java_arr[:])に非常に効率的に変換できるという大きな利点があります。

インストールプロセスは次のとおりです。

git clone https://github.com/originell/jpype.git
cd jpype
python setup.py install

そして、あなたはimport jpypeできるはずです

次のデモが機能しました:

import jpype as jp
jp.startJVM(jp.getDefaultJVMPath(), "-ea")
jp.Java.lang.System.out.println("hello world")
jp.shutdownJVM() 

独自のJavaコードを呼び出そうとしたとき、最初にコンパイル(javac ./blah/HelloWorldJPype.Java)する必要があり、JVMパスをデフォルトから変更する必要がありました(そうしないと、説明できない「クラスが見つかりません」 「エラー」。私にとって、これはstartJVMコマンドを次のように変更することを意味しました。

jp.startJVM('/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/MacOS/libjli.dylib', "-ea")
c = jp.JClass('blah.HelloWorldJPype')  
# Where my Java class file is in ./blah/HelloWorldJPype.class
...
5
Peter

Python 3にいる場合、 JPype1-py と呼ばれるJPypeのフォークがあります。

pip install JPype1-py3

これはOSX/Python 3.4.3で動作します。 (export Java_HOME=/Library/Java/JavaVirtualMachines/your-Java-versionが必要になる場合があります)

from jpype import *
startJVM(getDefaultJVMPath(), "-ea")
Java.lang.System.out.println("hello world")
shutdownJVM()
4
k107

私は最近、Javaを含むPythonに多くのものを統合しています。私が見つけた最も堅牢な方法は、IKVMとC#ラッパーを使用することです。

IKVMには、Java JARを取得して.Net DLLに直接変換できる、すてきな小さなアプリケーションがあります。 JVMバイトコードをCLRバイトコードに変換するだけです。詳細については、 http://sourceforge.net/p/ikvm/wiki/Ikvmc/ を参照してください。

変換されたライブラリはネイティブC#ライブラリと同じように動作し、JVMを必要とせずに使用できます。次に、C#DLLラッパープロジェクトを作成し、変換されたDLLへの参照を追加できます。

これで、公開するメソッドを呼び出すラッパースタブを作成し、それらのメソッドをDllEportとしてマークできます。詳細については、 https://stackoverflow.com/a/29854281/1977538 を参照してください。

ラッパーDLLはネイティブCライブラリのように機能し、エクスポートされたメソッドはエクスポートされたCメソッドのように見えます。通常どおりctypeを使用して接続できます。

Python 2.7で試しましたが、3.0でも動作するはずです。 WindowsおよびLinuxで動作します

たまたまC#を使用している場合、これは恐らくほとんどすべてをPythonに統合するときに試すのに最適なアプローチです。

2
Rob Deary

私はJPype 0.5.4.2(2011年7月)を使い始めたばかりで、うまく機能しているようです...
Xubuntu 10.04を使用しています

2
Joril

C++からJavaに到達できれば、すべて設定できていると思います。あなたが言及した種類の製品がうまく機能するのを見てきました。たまたま使用したのは CodeMesh でした。私はこのベンダーを明確に支持したり、製品の相対的な品質について述べたりするつもりはありませんが、非常に大量のシナリオで機能することを見てきました。

可能であれば、JNIを介した直接統合を避けることをお勧めします。いくつかの単純なRESTサービスアプローチ、またはキューベースのアーキテクチャは、開発と診断がより簡単になる傾向があります。このような分離されたテクノロジーを慎重に使用すると、かなりのパフォーマンスを得ることができます。

1
djna

Javaコードをpythonのpythonコード内で実行する方法と同様に、python ia内からいくつかのJavaコードを実行しようとする私自身の経験を通じて、簡単な方法論を見つけることができませんでした。

私の問題に対する私の解決策は、Javaを編集した後、pythonコード内からbeansシェルインタープリターをシェルコマンドとして呼び出して、このJavaコードをbeanshellスクリプトとして実行することでした。適切なパッケージと変数を使用して一時ファイルにコードを作成します。

私が話していることが何らかの形で役立つ場合、私のソリューションの詳細を共有できるように喜んでいます。

0
shady alaa