Keep on moving

あんまりまとまってないことを書きますよ

ThirdPartyLibrary + GraalVM+native-imageでCLIをつくってみる

masahito.hatenablog.com

でっかいエビーです。 これの続きを書きたいと思います。

name version
ubuntu 18.04 amd64
graalVM 1.0.0 RC2

TL;DL

  • GraalVM+native-image するときはFtatJar つくっちゃうと楽っぽい
    • 割と楽
  • native-image の実行は glibcが必要

  • Reflection/ Annotationが絡むと実行時エラーになるっぽい

    • Apache Commons とかは安心して使える. Spring系とかはかなりはまるかも

ラフに説明

用意するものがたくさんあるのでラフに説明します。exampleをつくってみたので以下を軽くみていただけると

github.com

3rd party library の使い方

ビルド時にclasspath宣言をしてビルドすることで3rd-partyライブラリを使うことが可能です。 例えばこんな感じ。

native-image --classpath=.:hoge.jar HelloWorld

ただ、数が増えてくると大変なのでfatJar(3rd-party Libraryをかためて一個にしたやつ , e.g. SpringBootとかでつくられる超でっかいJar)をつくるといいとおもいます。 ちなみにFatJarの場合はこんな感じでnative imegeがつくれます

native-image --jar=hoge.jar

これでhoge っていう名前の実行ファイルができます。

実行には glibcが必要

これでできたイメージを実行できるようになりました。 こんな感じでDocker Fileに実行ファイルをコピーするだけでとりあえず実行できるようになります。

graalvm-java-cli-native-demo/Dockerfile at master · masahitojp/graalvm-java-cli-native-demo · GitHub

$ docker build -t graalvm-test/run-test .
$ docker run -it -t graalvm-test/run-test:latest /bin/sh -c "./clitest -m test"

注意点が一個だけ。 native-image で生成された実行ファイルはglibcが必須です。 なるべく小さいdocker-imageが作りたくて素の alpine+dockerを試したんですが、 実行するとnot foucdっていう無情なエラーが出るだけでした。 alpine-glibcだと無事動作しました。 

ちなみにこの例だと19MiBくらいのdocker-imageになるようです。わりとちいさくまとまりますね1

github.com

Reflection/Annotation

もともとは Args4j を使ってexampleを書いてたんだけど、native-imageは作れるんだけど、 実行時にReflecttionのエラーがでちゃう。

ってのをTwitterでつぶやいたら教えてもらった。

ってのを教えてもらった。ありがたい。

medium.com

こちらのブログによると、

github.com

こんな感じでReflectionの対象になるであろうクラスを列挙したjsonをつくって渡してやればいいっぽい

[
  {
    "name": "io.netty.channel.socket.nio.NioServerSocketChannel",
    "methods": [
      { "name": "<init>", "parameterTypes": [] }
    ]
  }
]

まー今回は動かすのが目的なのでこの辺を調べるのはかつあいしました。詳しい方是非僕に説明よろしくです。

まとめ

結構かんたんにGraalVM+ native-imageをでnativeな実行ファイルを作れるようになりました。 JavaでFatJarつくれればそこから割とかんたんに作業をすることができるので、いろいろ遊んでみるといいと思います. Docker imageも20MiBくらいに収まりそうだし、ある程度遊べそうです

参考

先人の皆様に感謝します

  • sampleのcliの仕様はここからいただきました d.hatena.ne.jp
  • 信頼と実績のApache commons cli(reflection 使ってないっぽいので今回は悩まないために使った) Commons CLI – Home

  • 信頼と実績のkohsuke ware. Args4j

args4j parent - Args4j


  1. Go+scratchに比べると大きいけどね。