Upgrade to Pro — share decks privately, control downloads, hide ads and more …

GoからJavaのライブラリを使う #golangtokyo

GoからJavaのライブラリを使う #golangtokyo

2017-12-11 golang.tokyo #11
https://github.com/juntaki/javago
https://github.com/juntaki/jnigo

JNIでCからJavaのライブラリを呼び出す
https://qiita.com/juntaki/items/328d307583f406abc962

Jumpei Takiyasu

December 11, 2017
Tweet

More Decks by Jumpei Takiyasu

Other Decks in Technology

Transcript

  1. = &Me{ Name: "Jumpei Takiyasu", Company: "M3, Inc.", Github: "juntaki",

    Twitter: "juntaki", Web: "https://juntaki.com", }
  2. メモリ管理 JavaとCの変数をGoのオブジェクトでラップ runtime.Finalizerでまとめて開放 GoObject C (JNI) Java GetObject / malloc

    GetObject Object reference Pointer to Object ref. NewGlobalRef Go GC runtime.Finalizer DeleteGlobalRef free Java GC
  3. パフォーマンス対策 参考:Java Native Interface を使用する上でのベスト・プラクティス https://www.ibm.com/developerworks/jp/java/library/j-jni/index.html // FQCNでクラスを取得 jclass clazz

    = (*env)->FindClass(env, "Test"); // メソッド名とシグニチャで、メソッドIDを取得 jmethodID id = (*env)->GetStaticMethodID(env, clazz, "hello", "()V"); // 取得したクラスとメソッドID、引数を渡してメソッドを呼び出す。 (*env)->CallStaticVoidMethodA(env, clazz, id, NULL); クラスとメソッドIDは キャッシュして使いまわせる
  4. javapコマンドをパースしてコード生成 Javaっぽくjnigoを呼び出せるようにする $ javap -p -s java.lang.Math Compiled from "Math.java"

    public final class java.lang.Math { public static final double E; descriptor: D … public static float max(float, float); descriptor: (FF)F public static double max(double, double); descriptor: (DD)D (DD)D: 引数Double2つ 戻り値Doubleの意味
  5. Javaっぽさ func Mathmax(args ...interface{}) (jnigo.JObject, error) { convertedArgs, err :=

    jvm.ConvertAll(args) if err != nil { return nil, err } sigArgs := "" for _, arg := range convertedArgs { sigArgs += arg.Signature() } sigMap := map[string]string{"JJ":"(JJ)J", "FF":"(FF)F", "DD":"(DD)D", "II":"(II)I"} return jvm.CallStaticFunction( "java/lang/Math", "max", sigMap[sigArgs], convertedArgs) } メソッドオーバーロードをリフレクションで実現 コンパイル時に型チェックはできず、実行時に落ちるのが難点・・ Switch function signature by argument signatures