ビルド

このセクションでは、Spring Shell アプリケーションを構築する方法について説明します。

スターター

  1. Spring Shell スターター

名前 説明

spring-shell-starter

基本 Spring Shell モジュール

spring-shell-starter-jansi

JLine ジャンシプロバイダー

spring-shell-starter-jni

JLine jni プロバイダーを使用

spring-shell-starter-jna

JLine jna プロバイダー

spring-shell-starter-ffm

JLine ffm プロバイダー (requires JDK22+)

spring-shell-starter-test

Spring Shell テストサポート

ターミナルプロバイダー

プログラムが実行されている基盤となるターミナルとのやり取りは、従来、比較的複雑なプロセスでしたが、すべてがテキストだけなので、それほど多くのことは起こっていないように見えるかもしれません。

昔の手動型ライターやマトリックスプリンターを覚えていますか ? カーソルがある場所に文字が出力され、別の位置に出力する場合はカーソルを移動する必要があります。簡単に言えば、現在のターミナルエミュレーターはこのように動作します。

既存のターミナルエミュレーター環境にアクセスして理解を深めるために、JLine は独自の共有ライブラリを介してネイティブコードを使用できます。JLine は存在するプロバイダーを検出し、使用するプロバイダーを選択します。従来、jansijnijna の 3 つのプロバイダーがあり、すべて同じ機能を提供する必要があります。

当社のスターターを使用すると、これらの JLine プロバイダーのいくつかを具体的に選択できます。

FFM

JDK22 では、プレビューから外部関数およびメモリ API がリリースされ、JNI の代替として、より優れた安全なネイティブ API を提供するものになる予定です。

3.4.x から、Spring Shell アプリケーションを JLine ffm ターミナルプロバイダーでコンパイルするためのサポートを追加しました。これは明らかに、アプリケーションを JDK22+ で実行する必要があることを意味します。新しい JDK 中間リリースは 6 か月ごとに、長期サポート (LTS) リリースは 2 年ごとにあります。Spring Shell が Spring Framework と連携できる既存の LTS リリースが出るまでは、最新の JDK リリースを使用します。明らかに、これは ffm を使用することを選択した場合、都合の悪いときに JDK をアップグレードする必要がある可能性があることを意味します。また、JLine 自体が ffm 部分をコンパイルするために使用する JDK バージョンにも縛られます。

FFM itself will cause jvm to print warnings when some part of it are used. These warnings are obviously annoying with terminal applications as it may interfere and cause a little bit of a mess. In future JDK versions these warnings will also be added for an older JNI modules and at some point these warnings will be changed into hard errors. User will be required to enable these native "unsafe" parts manually.

JVM option for this in a command line is:

--enable-native-access=ALL-UNNAMED

If you have a jar file you can have this setting in its META-INF/MANIFEST.MF.

Enable-Native-Access: ALL-UNNAMED

Which can be added during a build i.e. if using gradle:

tasks.named("bootJar") {
    manifest {
        attributes 'Enable-Native-Access': 'ALL-UNNAMED'
    }
}
What comes for enabling native parts in a JDK, JLine has been proactive and already has a check for this and will throw error if native access is not enabled.

ネイティブサポート

Spring Shell アプリケーションを GraalVM バイナリにコンパイルするためのサポートは、主に Spring Framework および Spring Boot から提供され、機能は AOT と呼ばれます。アヘッドオブタイムとは、コンパイル時にアプリケーションコンテキストが準備され、GraalVM 生成の準備が整うことを意味します。

フレームワーク Spring Shell からの AOT 機能上に構築する独自の GraalVM 構成があり、バイナリに何が存在すべきかのヒントを提供します。通常、問題は、GraalVM 関連の構成がまだ含まれていないか、それらの構成が不完全なサードパーティライブラリから発生します。

サードパーティのライブラリに不足しているヒントを提供する GraalVM Reachability Metadata Repository を使用する必要があります。また、GraalVM をインストールし、それを指す JAVA_HOME  が必要です。

gradle の場合、graalvm のネイティブプラグインを追加し、メタデータリポジトリを構成します。

plugins {
	id 'org.graalvm.buildtools.native' version '0.9.16'
}

graalvmNative {
	metadataRepository {
        enabled = true
	}
}

gradle ビルドが ./gradlew nativeCompile で実行されると、build/native/nativeCompile ディレクトリにバイナリを取得する必要があります。

maven の場合、spring-boot-starter-parent を親として使用すると、コンパイルに使用できる native プロファイルが得られます。メタデータリポジトリを構成する必要があります

<build>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.graalvm.buildtools</groupId>
                <artifactId>native-maven-plugin</artifactId>
                <configuration>
                    <metadataRepository>
                        <enabled>true</enabled>
                    </metadataRepository>
                </configuration>
            </plugin>
        </plugins>
    </pluginManagement>
</build>
spring-boot-starter-parent に依存している場合は、最新に保たれている native-maven-plugin バージョンを管理します。

maven ビルドが ./mvnw native:compile -Pnative で実行されると、target ディレクトリにバイナリを取得する必要があります。

すべてがうまくいった場合、jvm を介して Boot アプリケーション jar を実行する代わりに、このバイナリをそのまま実行できます。