Doge log

Abby CTO 雑賀 力王のオフィシャルサイトです

Jythonから自分で作成したJavaクラスを呼んでみる

いきなり時間も書く事もないので困ったけど。
よくあるサンプルはjava標準のライブラリを呼ぶだけで終わっているものが多いのでちょっとサンプル挙げてみることにした。
確認したいこと

  1. jarファイルでなくてもimportは正しくできるか?(自分で作成したクラス)
  2. Python同様、getter/setterからでなく直接値にアクセスできるか?

まずJython(Python)のファイル。
属性に対しgetter経由でアクセスしていない事に注目。
java_import_test.py

from a.b.c.d.e import JavaImport
test = JavaImport()
print test.field

シンプルのフィールドの値にアクセスしコンソールに出力しています。

次に呼び出すJavaのクラス。
fieldはprivate、getter/setterがあることに注目。
JavaImport.java

package a.b.c.d.e;

/**
 * 
 * @author Yutaka Matsubara (゚∀゚)
 */
public class JavaImport {
    
    /**
     * 
     */
    private String field = "value";
    
    /**
     * JavaImportのコンストラクタ
     */
    public JavaImport() {
    }

    /**
     * @return field を戻します。
     */
    public String getField() {
        System.out.println("called getter");
        return this.field;
    }

    /**
     * @param field 設定します field。
     */
    public void setField(String aaa) {
        this.field = aaa;
    }
}

適当に1属性カプセル化したクラスです。

で実行クラス。
JythonSample .java

import java.net.URL;
import org.python.core.PyObject;
import org.python.util.PythonInterpreter;

/**
 * 
 * @author Yutaka Matsubara (゚∀゚)
 */
public class JythonSample {
    
    /**
     * 
     * @param args
     */
    public static void main(String[] args) throws Exception {
        // Pythonファイルを検索する
        String fqcn = JythonSample.class.getName();
        String resourcePath = fqcn.replace('.', '/') + ".class";
        URL url = Thread.currentThread().getContextClassLoader().getResource(resourcePath);
        String s = url.toString();
        s = s.substring(6, s.lastIndexOf("/") + 1) + "java_import_test.py";
        
        // 実行する
        PythonInterpreter pyi = new PythonInterpreter();
        pyi.execfile(s);
        
        // Pythonで処理した値を受け取る
        System.out.println("終了");
    }
}

実行結果

called getter
value
終了

問題なく呼べますね。importできてます。
更にgetterも自動で呼ばれます。なるほど。
但し、importに関しては元々のJythonのLib内にあるモジュールと名前がぶつかってしまうと動作しないので注意してください。
あとEclipseを使ってたりする場合、pyファイルの実行がうまくいかない場合があります。
PYTHONPATHに作成したクラスを追加してください。
(動的にPYTHONPATHを操作する方法は後日紹介する予定)
でgetterが勝手に呼ばれている理由は
フィールドがprivate
だからです。

Jythonで直接値にアクセスする場合

  1. アクセス修飾子のチェック(publicかどうか)
  2. getter/setterの存在チェック(public出ない場合)

が行われます。
そのためJavaImport.java

//    private String field = "value";
    public String field = "value";

のように変えると実行結果は以下のようになります。

value
終了

なるほど。こーいうのあったよね、確か。javaじゃなかったと思うけど。
えーっともうちょっと書きたいけど時間がないのでこの辺で。
うくく。