LoginSignup
3
5

More than 3 years have passed since last update.

【QUARKUS】KotlinとGradleでサンプル作ってネイティブ起動するところまで

Last updated at Posted at 2019-07-24

はじめに

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の中身はこんな感じになりました

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

このときquarkusBuildタスクの実行中に失敗するかもしれません
自分はsrc/main/resourcesの中に設定のpropertiesファイルが無かったのが原因でした
同様の現象が発生した場合はgradleのquarkusタスクにあるgenerateConfigを実行すると設定ファイルが作成されます
作成後に再度buildNativeをすればうまくいきました

実際にDockerにデプロイしていきます
Dockerfileを作成して

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周りの情報には期待していきたいですね。

3
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
5