PythonからJavaを呼び出す


123

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

JCCについて聞いたことがあります:http : //pypi.python.org/pypi/JCC/1.9 C ++ / PythonからJavaを呼び出すためのC ++コードジェネレーターしかし、これには可能な呼び出しをすべてコンパイルする必要があります。私は別の解決策を望みます。

JPypeについて聞いた:http : //jpype.sourceforge.net/ tutorial: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は死んだプロジェクトですか?

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

よろしく、デビッド


3
JythonとRPCがあなたの状況に選択肢ではないと思う理由を詳しく説明してください。
ネイサンデイビス

2
その間、新しいJPypeリリースがあったようです:2011-07-28の
0.5.4.2

回答:


51

これがこの問題の私の要約です:PythonからJavaを呼び出す5つの方法

http://baojie.org/blog/2014/06/16/call-java-from-python/キャッシュされました

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

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

Py4jはゲートウェイを起動する必要があるため、使用するのが少し難しいです。


135

Py4Jを使用することもできます。フロントページと多くのドキュメントに例がありますが、基本的には、PythonメソッドのようにPythonコードからJavaメソッドを呼び出すだけです。

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など)を使用できます。もう1つの部分は、呼び出すJava VMで実行されます。

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

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


リンクをありがとう。それは、djnaが提案したCodeMeshのオープンソースの代替手段のように見えます。私は間違いなくそれを見てみましょう。ただし、CodeMeshと同じ問題があり、Javaプロセスを開始してから、Pythonを使用する前に実行されていることを確認する必要があります(プロジェクトのメインWebページの例、ListPrinter.java-> main-> GatewayServer.start( ))。これが障害の原因となる可能性があります。JPypeのアプローチは素晴らしいと私はまだ思います。それだけが死んだプロジェクトのようです。
David Portabella、2009

8
@alvas私がPy4Jを維持しているのは、それがあなたの意図したものである場合です。
Barthelemy

@ Barthelemy、Javaコードがライブラリに依存している場合の統合方法-私の場合はopencv?

1
@stackは、クラスパスにopencvを必ず追加してください。GatewayServerを起動すると、Pythonからopencvにアクセスできるようになります。
Barthelemy

これはどのパッケージでも機能しますか?私が試した:s = gateway.jvm.ch.ethz.ssh2.crypto.Base64() bt_out = s.decode();ここで、Base64クラスにはメソッドencode()とdecode()がありch.ethz.ssh2.crypto、.jarファイルのパッケージの一部です。私が得るfrom py4j.reflection import MethodInvoker ImportError: No module named reflection
Vishal Sahu

19

ピュジュニウス。

ドキュメント: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

5

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
...

使用にJPypeビット容易にするために、小さなラッパーモジュールはここにある:github.com/petered/spiking-mlp/blob/master/spiking_mlp/...
ピーター・

4

Python 3を使用している場合、JPype1-py3と呼ばれる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

私は最近、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に統合するときに試す最善のアプローチです。


1
うーん...あなたはC#で私を失いました。これは一部のケースでは実行可能な可能性があるため、反対投票はしませんが、これは間違いなくWindowsや他の多くのものを想定しています。
Jared

2

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


1

私は、C ++からJavaに移行できる場合は、すべて準備が整っていると思います。あなたが言っている種類の製品がうまく機能するのを見てきました。たまたま使用したのはCodeMeshでした。私は特にこのベンダーを推奨したり、製品の相対的な品質について説明したりはしていませんが、かなり大量のシナリオで機能することを確認しました。

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


RPC(またはREST)は私の選択肢ではありません。
David Portabella、2009

これは、前にJavaプロセスを開始し、Pythonを使用する前に実行されていることを確認する必要があります。これが障害の原因となる可能性があります。JPypeのアプローチは優れています。それだけが死んだプロジェクトのようです。
David Portabella

一般的なアドバイスをしています。JNIは潜在的な地雷原です。
djna

0

私自身の経験から、いくつかのJavaコードをPython内から実行しようとしましたが、PythonコードがPythonのJavaコード内で実行されるのと同様の方法で、簡単な方法を見つけることができませんでした。

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

私が話していることが何らかの形で役立つ場合は、私の解決策の詳細を共有していただけると助かります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.