53
50

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PythonからJavaを呼び出す簡単な方法

Posted at

はじめに

py4jを使ってpythonからjavaのメソッドを呼び出す方法です。
日本語ドキュメントが古いものばかりで苦労したのでまとめてみました。

環境

OS X Yosemite 10.10.5
anaconda 3.5.0(python 3.5.2)

インストール

pip でpy4jをインストール後、Java側でpy4jを読み込めるようにjarをコピーします。

$ pip install py4j
$ sudo cp ~/.pyenv/versions/(仮想環境名)/share/py4j/py4j(バージョン).jar /Library/Java/Extensions/

実装

公式チュートリアルの通り、Javaで足し算を行う簡単なサンプルを作成してみます。
まずは以下のようなJavaプログラムを作成します。

AdditionApplication.java
import py4j.GatewayServer;

public class AdditionApplication {

  public int addition(int first, int second) {
    return first + second;
  }

  public static void main(String[] args) {
    AdditionApplication app = new AdditionApplication();
    // app を gateway.entry_point に設定
    GatewayServer server = new GatewayServer(app);
    server.start();
    System.out.println("Gateway Server Started")
  }
}

作成したら、以下のコマンドでサーバーを起動します。

$ javac AdditionApplication.java
$ java AdditionApplication

次に、AdditionApplication を呼び出すためのpythonプログラムを書いていきます。

from py4j.java_gateway import JavaGateway

# JVMへ接続
gateway = JavaGateway() 
# java.util.Randomインスタンスを作成
random = gateway.jvm.java.util.Random()   
# Random.nextIntを呼び出し
number1 = random.nextInt(10)              
number2 = random.nextInt(10)
print(number1,number2) # (2, 7)
#AdditionApplicationのインスタンスを取得
addition_app = gateway.entry_point        
# additionを呼び出し
sum_num=addition_app.addition(number1,number2)    
print(sum_num) # 9

ひとまずはpythonから呼び出せています。
ですが、サーバーの起動・停止をわざわざターミナルから行うのは若干手間です。
どうせなら、最初から最後までpythonで実行できるようにします。

# クラスパスを指定して実行
args=(["java","-cp",'/path/to/class/','AdditionApplication'])
p=subprocess.Popen(args)
# サーバー起動前に処理が下へ行くのを防ぐ
time.sleep(3) 
gateway = JavaGateway(start_callback_server=True)
random = gateway.jvm.java.util.Random()
n1 = random.nextInt(10)
n2 = random.nextInt(10)
print(number1,number2) # (2, 7)
addition_app = gateway.entry_point
print(addition_app.addition(n1, n2)) # 9
# プロセスをkill
gateway.shutdown()

最後まで一貫してpythonで実行できるようになりました。
Javerな人のプロジェクトを受け継いだ時や、使用したいJavaライブラリがある時、スピードの必要な処理を一部Javaで実装したい時等に使えるんじゃないでしょうか。

参考

https://www.py4j.org/
https://gist.github.com/bartdag/1070311

53
50
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
53
50

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?