開発を加速する Quarkus 2.0 で追加された Quarkus CLI

f:id:Naotsugu:20210901204009p:plain

blog1.mammb.com


はじめに

Quarkus 2.0 で追加された Quarkus Command Line Interface (Quarkus CLI) の使い方について説明します。Quarkus CLI は、Dev Services と共に Quarkus 2.0 の目玉機能となっています。

Quarkus CLI は現在プレビュー版となっていますが、開発時の一般的なワークフローは quarkus コマンドだけで済ませることができるようになっており、積極的に利用していきたいものとなっています。

ここでは Quarkus 2.2.1 をベースに話を進めることとします。


Quarkus CLI のインストール

Quarkus CLI は JBang を元にして動きます。

そのため、Quarkus CLI のインストールは以下のように jbang のインストールと JBang アプリケーションのインストールとして行います。

$ curl -Ls https://sh.jbang.dev | bash -s - app install --fresh --force quarkus@quarkusio

既に JBang がインストール済みであれば、以下のようにJBang アプリケーションのインストールを行います。

$ jbang app install --fresh --force quarkus@quarkusio

Quarkus CLI のアップデートは、以下のように JBang アプリケーションのアンインストール後に再度インストールすることで行えます。

$ jbang app uninstall quarkus
$ jbang app install --fresh --force quarkus@quarkusio


インストールは以下のように進みます。

Downloading JBang...
Installing JBang...
[jbang] Command installed: quarkus
[jbang] Setting up Jbang environment...
Please start a new Shell for changes to take effect

インストール時に .bash_profile.zshrc に以下が追加されます。

# Add Jbang to environment
alias j!=jbang
export PATH="$HOME/.jbang/bin:$PATH"

$HOME/.jbang には以下のようなコマンド群が配備されます。

$HOME/.jbang/
├── bin
│   ├── jbang
│   ├── jbang.cmd
│   ├── jbang.jar
│   ├── jbang.ps1
│   └── quarkus
├── cache
└── implicit-catalog.json

quarkus コマンドは以下のようなシェルスクリプトとなっています。

#!/bin/sh
exec jbang run quarkus@quarkusio "$@"

jbang により CLI 機能が提供されています。


SDKMan の場合は、以下のように JBang をインストールできるので、 JBang からアプリケーションをインストールすることもできます。

$ sdk install jbang

Homebrew の場合は以下のようになります。

$ brew install jbangdev/tap/jbang


Windows 環境での Quarkus CLI のインストール

Windows 環境では PowerShell にてインストールを行います。PowerShell 実行ポリシーを設定していない場合は以下の要領でポリシーを設定します。

> Set-ExecutionPolicy RemoteSigned -scope CurrentUser

インストールは以下のように行います。

> iex "& { $(iwr https://ps.jbang.dev) } app install --fresh --force quarkus@quarkusio"

環境変数に C:\Users\<user>\.jbang\bin が追加され、quarkus コマンドが利用可能となります。

quarkus.ps1 は以下の内容になっています。

jbang run quarkus@quarkusio $args

quarkus.cmd は以下の内容になっています。

@echo off
jbang run quarkus@quarkusio %*

いずれも jbang により Quarkus CLI を実行するようになっています。


Chocolatey の場合は、以下のように JBang をインストールできるので、 JBang からアプリケーションをインストールすることもできます。

> choco install jbang


Quarkus CLI コマンド

バージョンは以下のように確認できます。

$ quarkus --version
Client Version 2.2.1.Final


--help でヘルプを参照できます。

$ quarkus --help

Usage: quarkus [-ehv] [--verbose] [-D=<String=String>]... [COMMAND]

Options:
  -D=<String=String>    Java properties
  -e, --errors          Display error messages.
  -h, --help            Show this help message and exit.
  -v, --version         Print version information and exit.
      --verbose         Verbose mode.

Commands:
  create              Create a new project.
    app               Create a Quarkus application project.
    cli               Create a Quarkus command-line project.
  build               Build the current project.
  dev                 Run the current project in dev (live coding) mode.
  extension, ext      List, add, and remove extensions of an existing project.
    list, ls          List platforms and extensions.
    categories, cat   List extension categories.
    add               Add a Quarkus extension registry to the registry client
                        configuration
    remove, rm        Remove extension(s) from this project.
  registry            Manage extension registries.
    list              List enabled Quarkus registries
    remove            Remove a Quarkus extension registry from the registry
                        client configuration
  version             Display version information.
  completion          bash/zsh completion:  source <(quarkus completion)

主な使い方は以下のようになります。

  • quarkus create app でプロジェクトを作成
  • quarkus ext ls -i -s=xxx で extension を探す
  • quarkus ext add xxx で extension プロジェクトに追加する
  • quarkus dev でアプリケーションを起動してライブコーディングする
  • quarkus build でアプリケーションをビルドする
    • java -jar ./build/quarkus-app/quarkus-run.jar で実行可能
  • quarkus build -native でネイティブビルドする(要GraalVM)


プロジェクトの作成

Quarkus CLI コマンドで最初に行うのは、プロジェクトの生成になります。

プロジェクトは、アプリケーションプロジェクトとコマンドラインプロジェクトの2つがあり、それぞれ以下のコマンドが有ります。

$ quarkus create app
$ quarkus create cli

ここでは、アプリケーションプロジェクトについて見ていくことにしましょう。


プロジェクトの作成は、オプション指定しない場合は、デフォルトの構成でプロジェクトが作成されます。

$ quarkus create app
-----------

applying codestarts...
📚  java
🔨  maven
📦  quarkus
📝  config-properties
🔧  dockerfiles
🔧  maven-wrapper
🚀  resteasy-codestart

-----------
[SUCCESS] ✅  quarkus project has been successfully generated in:
--> /<path>/code-with-quarkus
-----------
Navigate into this directory and get started: quarkus dev

デフォルトでは、Java の Maven プロジェクトで、アーティストIDには org.acme:code-with-quarkus:1.0.0-SNAPSHOT が設定されます。

カレントの code-with-quarkus というディレクトリに以下のようなプロジェクトが作成されます。

.
├── README.md
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
    ├── main
    │   ├── docker
    │   │   ├── Dockerfile.jvm
    │   │   ├── Dockerfile.legacy-jar
    │   │   ├── Dockerfile.native
    │   │   └── Dockerfile.native-distroless
    │   ├── java
    │   │   └── org
    │   │       └── acme
    │   │           └── GreetingResource.java
    │   └── resources
    │       ├── META-INF
    │       │   └── resources
    │       │       └── index.html
    │       └── application.properties
    └── test
        └── java
            └── org
                └── acme
                    ├── GreetingResourceTest.java
                    └── NativeGreetingResourceIT.java

デフォルト構成を変更するには、オプションを指定します。

オプションは以下で照会することが出来ます(長いので省略します)。

$ quarkus create app --help

Create a Quarkus application project.

Usage: quarkus create app [-Beh] [--dry-run] [--refresh] [--[no-]
                          registry-client] [--verbose] [-o=OUTPUT-DIR]
                          [-D=<String=String>]... [-x=EXTENSION[,
                          EXTENSION...]]... [-S=platformKey:streamId |
                          -P=groupId:artifactId:version] [--jbang | --maven |
                          --gradle | --gradle-kotlin-dsl] [--java | --kotlin |
                          --scala] [[--[no-]wrapper] [--[no-]code]
                          [--package-name=PACKAGE-NAME] [-c=<appConfig>]]
                          [[GROUP-ID:]ARTIFACT-ID[:VERSION]]
// ...

よく使うオプションは以下になるかと思います。

  • Quarkus バージョン --stream=io.quarkus.platform:2.2.1
  • ビルドツール指定 --maven --gradle --gradle-kotlin-dsl
  • 言語 --java --kotlin --scala
  • artifactid  [GROUP-ID:]ARTIFACT-ID[:VERSION] の形式で指定

Quarkus 2.2.1 時点では、--gradle-kotlin-dsl を指定した場合、language は強制的に --kotlin が指定されたものとなります。

Gradle の Java プロジェクトは以下のように作成することになります。

$ quarkus create app --gradle --java com.mammb:quarkus-sample:0.1.0

-----------

applying codestarts...
📚  java
🔨  gradle
📦  quarkus
📝  config-properties
🔧  dockerfiles
🔧  gradle-wrapper
🚀  resteasy-codestart

-----------
[SUCCESS] ✅  quarkus project has been successfully generated in:
--> /<path>/quarkus-sample
-----------
Navigate into this directory and get started: quarkus dev

以下のような構成でプロジェクトが作成されます。

.
├── README.md
├── build.gradle
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
    ├── main
    │   ├── docker
    │   │   ├── Dockerfile.jvm
    │   │   ├── Dockerfile.legacy-jar
    │   │   ├── Dockerfile.native
    │   │   └── Dockerfile.native-distroless
    │   ├── java
    │   │   └── com
    │   │       └── mammb
    │   │           └── GreetingResource.java
    │   └── resources
    │       ├── META-INF
    │       │   └── resources
    │       │       └── index.html
    │       └── application.properties
    ├── native-test
    │   └── java
    │       └── com
    │           └── mammb
    │               └── NativeGreetingResourceIT.java
    └── test
        └── java
            └── com
                └── mammb
                    └── GreetingResourceTest.java


Extension の追加

Extension の検索や追加も quarkus コマンドで行うことができます。

オプションは以下のようになります。

$ quarkus ext --help

List, add, and remove extensions of an existing project.

Usage: quarkus extension [-eh] [--refresh] [--[no-]registry-client] [--verbose]
                         [-D=<String=String>]... [COMMAND]
Options:
  -e, --errors          Display error messages.
      --verbose         Verbose mode.
      --refresh         Refresh the local Quarkus extension registry cache
      --[no-]registry-client
                        Use the Quarkus extension catalog
  -h, --help            Display this help message.
  -D=<String=String>    Java properties

Commands:
  list, ls         List platforms and extensions.
  categories, cat  List extension categories.
  add              Add extension(s) to this project.
  remove, rm       Remove extension(s) from this project.

それぞれのコマンドは、プロジェクトディレクトリ内で実行した場合と、外部で実行した場合で挙動が異なります。プロジェクトディレクトリ内で実行した場合は、そのプロジェクトに応じた動作となります(プロジェクトディレクトリ内で実行する場合が大抵と思いますので、その内容についてのみ説明します)。

主な使い方は以下のようになります。

  • quarkus ext ls -i -s=xxx で Extension を探す
    • -i でインストール可能な Extension を出力。指定しない場合は現在導入済みのExtension を出力
    • -s=xxx でキーワードを指定する
    • -c=xxx でカテゴリを絞って出力する
    • --concise で Extension名と artifactId を出力する(デフォルトは artifactId のみ)
    • --full--concise に加えてバージョン情報などを含める
  • quarkus ext cat でカテゴリ一覧を照会する
  • quarkus add <artifactId> で Extension を導入する
    • Gradle や Maven の 依存に追加される
  • quarkus rm <artifactId> で Extension を削除する
    • Gradle や Maven の 依存から削除される

例えば以下のようにすることで、

$ quarkus ext add quarkus-hibernate-orm-rest-data-panache quarkus-jdbc-postgresql

> Task :addExtension
[SUCCESS] ✅  Extension io.quarkus:quarkus-jdbc-postgresql has been installed
[SUCCESS] ✅  Extension io.quarkus:quarkus-hibernate-orm-rest-data-panache has been installed

BUILD SUCCESSFUL in 1s
1 actionable task: 1 executed

以下のように依存が追加されます。

dependencies {
    implementation 'io.quarkus:quarkus-hibernate-orm-rest-data-panache'
    implementation 'io.quarkus:quarkus-jdbc-postgresql'
    // ...
}


開発モードで起動

プロジェクト内で以下とすることで開発モードでアプリケーションが起動します。

$ quarkus dev

なお、Quarkus 2.1.3 では Gradle 6.9 としてプロジェクトが作成されるため、Java16 で動かすには gradle/wrapper/gradle-wrapper.properties を編集し、gradle-7.2-bin.zip など7系を指定する必要があります。

[http://localhost:8080/hello](http://localhost:8080/hello) にアクセスすれば以下のようなスタートページが表示されます。

f:id:Naotsugu:20210901203834p:plain

開発モードでは、ソースの変更が即座に反映されるライブコーディングが可能です。

Dev Services によるテストの自動実行もサポートされます。r キーにより継続テストが実行できます。

また、中ほどのリンクの Dev UI からプロジェクトの Config を画面から変更することもできます。

f:id:Naotsugu:20210901203814p:plain

開発モードのヘルプは以下で照会できます。

$ quarkus dev --help


プロジェクトビルド

作成したプロジェクトのビルドは以下で行います。

$ quarkus build

オプションは以下の通りとなっています。

$ quarkus build --help

Build the current project.

Usage: quarkus build [-Beh] [--[no-]clean] [--dry-run] [--native] [--[no-]
                     tests] [--offline] [--refresh] [--[no-]registry-client]
                     [--verbose] [-D=<String=String>]... [--] [<params>...]

      [<params>...]     Additional parameters passed to the build system
                          Default: []
Options:
  -e, --errors          Display error messages.
      --verbose         Verbose mode.
      --refresh         Refresh the local Quarkus extension registry cache
      --[no-]registry-client
                        Use the Quarkus extension catalog
  -h, --help            Display this help message.
  -D=<String=String>    Java properties
  -B, --batch-mode      Run in non-interactive (batch) mode.
      --dry-run         Show actions that would be taken.

Build options:
      --[no-]clean      Perform clean as part of build. False by default.
      --native          Build native executable.
      --offline         Work offline.
      --[no-]tests      Run tests.
  --                    End of command line options.

プロジェクトのビルドが完了すれば、build/quarkus-app 以下に成果物が作成されます。

以下で実行することができます。

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

GraalVM が導入済みで、GRAALVM_HOME が定義してあれば、以下でネイティブイメージが作成できます。

$ quarkus build --native


GraalVM が無くとも、Docker コンテナでネイティブイメージをビルドすることもできます。

$ quarkus build --native -D=quarkus.native.container-build=true

Linux 用のネイティブイメージが作成されます(大量のメモリが必要なため、Docker 側のメモリを 8G 以上にしておくと良いです)。また、ビルドは概ね5分以上はかかりますので注意してください。

src/main/docker/Dockerfile.native には予め Dockerfile が用意されているため、以下でコンテナイメージを作成できます。

$ docker build -f src/main/docker/Dockerfile.native -t quarkus-quickstart/getting-started .

コンテナイメージの作成用の Extension を使うこともできます。


コンテナイメージの作成

コンテナイメージの作成用に以下の Extension が提供されています。

  • quarkus-container-image-docker
  • quarkus-container-image-jib
  • quarkus-container-image-openshift
  • quarkus-container-image-s2i

Extension を追加し、

$ quarkus ext add quarkus-container-image-docker

以下で、アプリケーションを含む Docker コンテナイメージが作成できます。

$ quarkus build --native -D=quarkus.native.container-build=true -Dquarkus.container-image.build=true

作成されたイメージを確認し、

$ docker images

REPOSITORY         TAG    IMAGE ID            CREATED             SIZE
<IMAGE_NAME>   0.1.0   4d7678e33ac8   16 seconds ago   166MB

実行

$ docker run -it --rm -p 8080:8080 <IMAGE_NAME>:<TAG>

ミリ秒オーダーで起動します。


まとめ

Quarkus 2.0 で追加された Quarkus Command Line Interface (Quarkus CLI) の使い方について説明しました。

基本的な開発フローは quarkus コマンドで完結し、例えばビルドツールに何を使っているかも特に気にする必要すらありません。Dev UI と Dev Services といった開発ツールも含めて、包括的な開発体験を得られるようになっています(あとは、導入した Extension に応じた scaffold が提供されると素晴らしくなりそうです)。

具体的なアプリケーション作成の流れは以下を参照してください。

blog1.mammb.com

みなさんも試してみてはいかがでしょうか。