Quarkus 入門 – Hello World とネイティブビルド

システム開発事業部

開発言語: Java

Quarkus は、クラウドネイティブ、コンテナファースト向けに作成されたJavaフレームワークです。
今回は Get Started をやってみます。
動作環境は Ubuntu 20.04.3 LTS、Quarkus は 2.7.1 です。

事前準備

まず、JDKと関連ツールのインストールを行えるようにするため、SDKMAN! のインストールを行います。
curlのインストール後、SDKMAN!のインストールを実行します。

$ sudo apt-get install curl
$ curl -s "https://get.sdkman.io" | bash

SDKMAN!を有効化するため、一度ターミナルを再起動します。

次にJavaをインストールします。
ここでは、Eclipse Temurin™プロジェクトのJDKを利用します。
(Javaのバージョンは11以上(Quarkus 2.7.1時点)であれば概ね問題ないと思います。)

$ sdk install java 17.0.2-tem

これで最低限のJavaの開発環境ができました。

Get Started

次にQuarkus CLIをインストールします。

$ sdk install quarkus 2.7.1.Final

Get Started用のアプリケーションを作成します。
適当なディレクトリに移動して、CLIで作成します。
code-with-quarkusというディレクトリが作成されるので、プロジェクトのディレクトリに移動します。

$ quarkus create
$ cd code-with-quarkus

開発モードでアプリケーションの起動をします。

$ quarkus dev

http://localhost:8080/hello へアクセスすると、Hello RESTEasyとレスポンスされます。

この実装は、 src/main/java/GreetingsResource.java でされています。
ここで、レスポンスを少し変えてみると、開発モードで起動した場合、アプリケーションがリロードされます。
ソースコードを変更するたびに手動で再起動しなくて済むので非常に楽です。

jarパッケージングとアプリケーションの起動について

Get Startedの下部にあるNext Stepsでネイティブ実行可能なビルド方法について案内が出ていますが、先に従来のアプリケーション起動について記載します。
(これは、Get Startedで作成したプロジェクトのREADME.mdに書いてあります。)
パッケージング方法は2種類あり、fast-jar(デフォルト)とuber-jar(全部入りのjar)です。

まず、fast-jarの作成は、以下の通りです。

$ quarkus build
# mavenで実行する場合は以下の通り
$ ./mvnw package

target/quarkus-app/というディレクトリが作成されます。
fast-jarの場合、エントリーポイントはquarkus-run.jarです。
なお、target/quarkus-app/以下のファイルは全て必要です。
実行方法は通常のjar実行と同じです。

$ java -jar target/quarkus-app/quarkus-run.jar

続いて、uber-jarの作成方法は、以下の通りです。

$ quarkus build -Dquarkus.package.type=uber-jar
# mavenで実行する場合は以下の通り
$ ./mvnw package -Dquarkus.package.type=uber-jar

target/code-with-quarkus-1.0.0-SNAPSHOT-runner.jar が作成されます。
(quarkus.package.type=uber-jar については、src/resources/application.properties へ記載しておけば、quarkus build (または./mvnw package) で同様の結果となります。)

こちらも実行方法は通常のjar実行と同じです。

$ java -jar target/code-with-quarkus-1.0.0-SNAPSHOT-runner.jar

ちなみに、システムプロパティを指定しない場合(fas-jar作成時)に作成される target/code-with-quarkus-1.0.0-SNAPSHOT.jar は実行できません。
また、uber-jar作成時は、このjarファイルは、target/code-with-quarkus-1.0.0-SNAPSHOT.jar.original として生成されます。

ネイティブ実行可能なアプリのビルドについて

公式ドキュメントに沿って実行します。

最初に、ネイティブコンパイルに必要なライブラリを追加します。

# ドキュメントには libz-dev も記載されていましたが、今回は不要でした。
$ sudo apt-get install build-essential zlib1g-dev

次に、ビルドにはGraalVM(バージョン21.3.1)が必要なので、インストールします。
MandrelというQuarkus向けに開発された、GraalVMコミュニティディストリビューションがありますが、ここでは利用しません。

sdk install java 21.3.1.r17-grl

次にビルド時に実用な環境変数を設定します。

# 以下はSDKMAN!の例です。GraalVMのインストールパスを指定します。
$ export GRAALVM_HOME=$HOME/.sdkman/candidates/java/21.3.1.r17-grl/

ビルドに必要なツールをインストールします。(Mandrelの場合は不要なようです。)

$ ${GRAALVM_HOME}/bin/gu install native-image

これでビルドできるようになったので、ビルドします。(jar作成時に比べて時間がかかります。)

$ quarkus build --native
# mavenで実行する場合は以下の通り
$ ./mvnw package -Pnative

target/code-with-quarkus-1.0.0-SNAPSHOT-runner という実行可能ファイルが作成されます。
このファイルを実行すればアプリケーションが起動します。(先ほど設定した環境変数も不要です。)

$ ./target/code-with-quarkus-1.0.0-SNAPSHOT-runner

以上で一通りのアプリケーション実行ができるようになりました。

感想

初期状態で実行可能ファイルが1箇所に固まるようにしてくれているので、リリースは非常に簡単です。
ビルド関連の設定はたくさんあるようですが、簡単なアプリケーションであれば特に設定を変更せずとも困ることは少ないかもしれません。

Get Started(かつコードが洗練されている)なので簡単にできて当たり前かもしれませんが、初期状態のOSで環境構築をすると何も入っていない(特にcurlやbuild-essential)ということを忘れて飛ばし読みしてやった結果、意外と時間がかかってしまいました。

Quarkusを利用するような場合、最新のCI/CDを使うと考えられ、リリースのためのビルドにはコンテナを利用すると考えられるので、ローカル環境では開発モードが起動(quarkus dev)できれば十分かもしれません。
一方で、マシンリソースやネットワーク環境の関係でローカル環境でのビルドの方が早いケースは多いと思います。急にビルドできなくなった際の確認といった時に、こまめにビルドして調べたいような場合に使えるので、手元でビルドできるようにしておいて損はないと思います。

関連記事

カテゴリー

アーカイブ