今回はPythonからJavaを呼び出してみます。過去の資産を有効利用するという意味でJavaを呼び出せるメリットは大きいです。
グルーコードのテクニックを知っていると改修すべきプログラムをそのまま利用できることがあります。
以前.NETとJavaの同時呼び出しを記事にしたことがありますが、Javaの資産をJNI->C->C++/CLI->.NETを経由して.NETから利用したことがあり、そのとき一部をメモしたものです。
http://crossframe.iiv.jp/2013021475/
下記、pyjniusというモジュールを使ってJavaクラスを利用してみました。
https://pypi.org/project/pyjnius/
こちらにあるサンプルコードに追加してユーザクラスも試してみました。
環境)Python 3.8, Java 11 / WSL2 / Windows 11
インストール
$ pip3 install pyjnius
Collecting pyjnius
Downloading pyjnius-1.6.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.6 MB)
|████████████████████████████████| 1.6 MB 2.8 MB/s
Installing collected packages: pyjnius
Successfully installed pyjnius-1.6.1
Users.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class Users{ private int id; private String name; public Users(int id, String name){ this.id = id; this.name = name; } public int getId(){ return id; } public String getName(){ return name; } } |
次にJavaVMでうごかすPython、Jythonについても取り上げてみたいと思います。JythonはPython ver3をサポートしていないようですので、あまり使う機会がないかもしれませんが、過去によくみかけた実装で今の環境でも動くのか興味があったので試してみました。
参考) https://qiita.com/ht12345/items/d1de737e3549fca64c1b
まず下記サンプルコードを確認しました。
https://www.jython.org/
1 2 3 4 5 6 7 8 9 |
import org.python.util.PythonInterpreter; public class JythonHelloWorld { public static void main(String[] args) { try(PythonInterpreter pyInterp = new PythonInterpreter()) { pyInterp.exec("print('Hello Python World!')"); } } } |
インストール
$ wget https://repo1.maven.org/maven2/org/python/jython-installer/2.7.3/jython-installer-2.7.3.jar
$ java -jar jython-installer-2.7.3.jar –console
Welcome to Jython !
You are about to install Jython version 2.7.3
(at any time, answer c to cancel the installation)
For the installation process, the following languages are available: English, German
Please select your language [E/g] >>>
Do you want to read the license agreement now ? [y/N] >>>
Do you accept the license agreement ? [Y/n] >>>
The following installation types are available:
1. All (everything, including sources)
2. Standard (core, library modules, demos and examples, documentation)
3. Minimum (core)
9. Standalone (a single, executable .jar)
Please select the installation type [ 1 /2/3/9] >>> 9
Please enter the target directory >>> .
Directory /home/k/python/java is not empty – ok to overwrite contents ? [y/N] >>>
Please enter the target directory >>> target
Unable to find directory /home/k/python/java/target, create it ? [Y/n] >>>
Your java version to start Jython is: Ubuntu / 11.0.18
Your operating system version is: Linux / 5.10.16.3-microsoft-standard-WSL2
Summary:
– standalone
Please confirm copying of files to directory /home/k/python/java/target [Y/n] >>>
targetディレクトリに生成されはjarファイルをカレントに持ってきて使用します。
Pythonコードは以下のようにして実行できました。(任意)
$ java -jar jython.jar test.py
JythonHelloWorld.java をコンパイルします。
$ javac JythonHelloWorld.java -cp jython.jar
実行
$ java -classpath .:jython.jar JythonHelloWorld
Hello Python World!
本題のPythonコードの実行で変数がJavaとやりとりされている下記にあるサンプルコードを動かしてみます。
参考) https://qiita.com/ht12345/items/d1de737e3549fca64c1b
ScriptDemo.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
import javax.script.*; import org.python.core.PyInteger; public class ScriptDemo{ public static void main(String[] args) throws ScriptException { String script = "from decimal import Decimal\n" + "y = num + Decimal(10)"; ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName("python"); SimpleBindings bindings = new SimpleBindings(); PyInteger num = new PyInteger(5); bindings.put("num", num); scriptEngine.eval(script, bindings); Object y = bindings.get("y"); System.out.println(y); System.out.println(y.getClass()); } } |
コンパイルと実行
$ javac ScriptDemo.java -cp jython.jar
$ java -cp .:jython.jar ScriptDemo
15
class java.math.BigDecimal
無事、私の環境で動作することを確認できました。
コードサンプルでは、環境違いで動かないことや、よくimport文がなかったりビルド方法が明示されていないケースがあったりしますので、実際に動かしてみることで、理解が深まり安心できます。