Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

はじめに

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

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away