【QUARKUS】KotlinとGradleでサンプル作ってネイティブ起動するところまで
はじめに
QUARKUS触ってみたいなーと前々から思っていたので、KotlinとGradleを使ったQUARKUSのサンプルを作ってみました QUARKUSのドキュメントではmavenのほうが情報が厚そうだったのですが、pom.xml書きたくない、スクリプトで依存性管理したいと思ったのでGradleを選択しました とりあえず今回はネイティブイメージをビルドするところまでです また、自分はmacを使っているのでmacユーザー向けに書いていきます
作成したコードのリポジトリはこちらになります https://github.com/yoshi10321/sample-quarkus-app
GraalVMのインストール
まずGraalVMをインストールします
https://github.com/oracle/graal/releases
macの場合
graalvm-ce-darwin-amd64-{バージョン名}.tar.gz
というファイルをダンロードして解凍します
解凍したディレクトリを
/Library/Java/JavaVirtualMachines
に移動しておきます
/usr/libexec/java_home -V
コマンドを叩くとインストールしてあるJavaのバージョンが見れます
GraalVMがあればOK
環境変数にセットしてGraalVMを使うようにします
export JAVA_HOME=$(/usr/libexec/java_home -v 1.8) export PATH=$JAVA_HOME/bin:$PATH
次にネイティブイメージ作成用にnative-image
ツールをインストールしておきます
gu install native-image
ここまでやったらGraalVMのインストールは完了です
Gradleプロジェクトの作成
mavenだと便利なQUAKUSプロジェクト作成用のコマンドが用意されているようですが、現状Gradleではまだそういった便利なものは用意されてなかったので自分で作っていきます
まず好きなディレクトリを作成してそこに移動しておきます
mkdir sample-quarkus-app cd sample-quarkus-app
下記のコマンドでgradleのkotlinプロジェクトが作成できます
gradle init --type=kotlin-application
QUARKUSの設定を追加していく
まずQUARKUSのGradle pluginがまだGradle Plugin Portalに上がってないから./settings.gradle.kts
に下記のコードを追加します
pluginManagement { repositories { mavenCentral() gradlePluginPortal() } resolutionStrategy { eachPlugin { if (requested.id.id == "io.quarkus") { useModule("io.quarkus:quarkus-gradle-plugin:${requested.version}") } } } }
次にbuild.gradle.kts
の中身はこんな感じになりました
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet plugins { // Apply the Kotlin JVM plugin to add support for Kotlin on the JVM. id("org.jetbrains.kotlin.jvm").version("1.3.31") id("org.jetbrains.kotlin.plugin.allopen") version "1.3.41" java id("io.quarkus") version "0.19.1" } allOpen { annotation("javax.ws.rs.Path") annotation("javax.enterprise.context.ApplicationScoped") annotation("sample.quarkus.app.MyAnnotation") } repositories { jcenter() mavenCentral() } dependencies { implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") implementation(enforcedPlatform("io.quarkus:quarkus-bom:0.19.1")) implementation("io.quarkus:quarkus-resteasy") implementation("io.quarkus:quarkus-resteasy-jsonb") implementation("io.quarkus:quarkus-kotlin") testImplementation("org.jetbrains.kotlin:kotlin-test") testImplementation("org.jetbrains.kotlin:kotlin-test-junit") testImplementation("io.quarkus:quarkus-junit5") testImplementation("io.rest-assured:rest-assured:3.1.0") } quarkus { setSourceDir(project.projectDir.resolve("src/main/kotlin").absolutePath) setOutputDirectory(project.projectDir.resolve("build/classes/kotlin/main").absolutePath) } kotlin.sourceSets["test"].kotlin.srcDirs("test")
build.gradleの設定で自分が少しハマったところを書いておくと
sourceDir
を設定しないと./gradlew quarkusDev
で起動した時にエラーが発生しますimplementation("io.quarkus:quarkus-resteasy-jsonb")
これを入れないと
@GET @Produces(MediaType.APPLICATION_JSON) fun hello() = Greeting("hello")
このコードのようなjsonフォーマットでレスポンスを返すときのjsonシリアライズでコケました
implementation("io.quarkus:quarkus-kotlin")
これを入れないとkotlinで書いたコードのホットリロードがうまく動かなかったです- kotlinのクラスはデフォルトで
final
クラスになってしまうのでallopenプラグインを使ってopenにします。ただなぜかApplicationScopedアノテーションを付けたクラスでうまく効いてくれなかったので、別途手動でopenをつけたりもしました。(原因調べきれてないです、すいません)
下記のコマンドで起動することで、ホットリロードが有効な状態で起動できます
./gradlew quarkusDev
ブラウザでlocalhost:8080/hello
にアクセスするとjsonのレスポンスが返ってくるのが確認できます
Kotlinのコードはgithubの方を参照していただければと思います https://github.com/yoshi10321/sample-quarkus-app
ネイティブイメージのビルド
環境変数にGRAALVM_HOME
をセットしておく必要があります
macの場合は下記のように設定します
export GRAALVM_HOME=$HOME/Development/graalvm/Contents/Home/
docker向けにネイティブビルドする場合は下記のコマンドを叩きます
./gradlew buildNative --docker-build=true
実際にDockerにデプロイしていきます Dockerfileを作成して
FROM registry.access.redhat.com/ubi8/ubi-minimal WORKDIR /work/ COPY build/*-runner /work/application RUN chmod 775 /work EXPOSE 8080 CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
下記のコマンドでDocker build&runしていきます
docker build -f Dockerfile -t sample/quarkus-app . docker run -i --rm -p 8080:8080 sample/quarkus-app
-> % docker run -i --rm -p 8080:8080 sample/quarkus-app 2019-07-21 16:50:38,190 INFO [io.quarkus] (main) Quarkus 0.19.1 started in 0.013s. Listening on: http://0.0.0.0:8080 2019-07-21 16:50:38,191 INFO [io.quarkus] (main) Installed features: [cdi, kotlin, resteasy, resteasy-jsonb]
0.013秒で起動したというログが確認できました。 Kotlinで書いたコードがこの速さで起動するのは感動ものです
終わりに
少しハマったところもありましたがQUARKUSのアプリケーションをKotlinとGradleを使ってネイティブ起動するところまでいけました ネイティブコードで実行することでJVMの起動が遅い問題が回避できるため、Kubernetes上で起動させたときのオートスケーリング時のパラメータ設定にそこまで気を使わなくても良くなるんじゃないかなということを期待しています 今後も特にQUARKUS, GraalVM周りの情報には期待していきたいですね。