ネイティブ イメージをコンパイルする

Java 用 Cloud クライアント ライブラリを使用すると、アプリケーションをネイティブ イメージとしてコンパイルできます。このアプローチでは、事前コンパイルを利用してアプリケーションのコールド スタートアップ時間とメモリ フットプリントを削減することで、アプリケーションのパフォーマンスを向上させます。

クライアント ライブラリのバージョン

Cloud Libraries の部品構成表libraries-bom)のバージョン 25.4.0 以降を使用しているか、2022 年 5 月以降に公開されたクライアント ライブラリを使用していることを確認します。

ほとんどのユーザーは libraries-bom を使用してクライアント ライブラリのバージョンを管理しています。これは、プロジェクト内のすべてのクライアント ライブラリのバージョンが互いに互換性があり、最新であることを簡単に確認する方法です。

Maven と Gradle で libraries-bom をプロジェクトに適用する方法については、BOM を使用するようにプロジェクトを更新するをご覧ください。

サポートされているライブラリ

サポートされている API の表に記載されている安定版の Java 用 Google Cloud クライアント ライブラリは、ネイティブ イメージ コンパイルをサポートしています。

始める前に

目的の Java 用 Google Cloud クライアント ライブラリでネイティブ イメージ コンパイルを使用するには、次の前提条件の手順を行います。

  1. まだ作成していない場合は、Google Cloud プロジェクトを作成します。

  2. Google Cloud CLI をインストールします。これにより、プロジェクトの認証情報を使用してサンプルを実行できます。

  3. Google Cloud CLI をインストールしたら、次のコマンドを使用してアプリケーションのデフォルト認証情報でログインします。

    gcloud auth application-default login
    
  4. GraalVM などの適切な JDK ディストリビューションをインストールします。

  5. 次のコマンドを実行して、ネイティブ イメージ拡張機能をインストールしたことを確認します。

    gu install native-image
    
  6. ターミナルで java -version を実行して、Java のデフォルト バージョンが正しく設定されていることを確認します。出力は次のようになります。

    java -version
    openjdk version "17.0.9" 2023-10-17
    OpenJDK Runtime Environment GraalVM CE 17.0.9+9.1 (build 17.0.9+9-jvmci-23.0-b22)
    OpenJDK 64-Bit Server VM GraalVM CE 17.0.9+9.1 (build 17.0.9+9-jvmci-23.0-b22, mixed mode, sharing)
    

アプリケーションをネイティブ イメージとしてビルドする

次の手順では、ネイティブ ビルドツール プラグインを使用して、アプリケーションをネイティブ イメージとしてビルドします。

Maven のセットアップ手順

  1. このテキストをアプリケーションの POM にコピーして貼り付け、ネイティブ Maven プラグインを使用してアプリケーションのネイティブ イメージをビルドします。MAIN_CLASS はメインクラスの名前に、VERSION はネイティブ Maven プラグインのバージョン(0.10.1 など)に置き換えてください。

    <profiles>
        <profile>
            <id>native</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.graalvm.buildtools</groupId>
                        <artifactId>native-maven-plugin</artifactId>
                        <version>VERSION</version>
                        <extensions>true</extensions>
                        <configuration>
                            <mainClass>$MAIN_CLASS</mainClass>
                            <buildArgs>
                                <buildArg>--no-fallback</buildArg>
                                <buildArg>--no-server</buildArg>
                            </buildArgs>
                        </configuration>
                        <executions>
                            <execution>
                                <id>build-native</id>
                                <goals>
                                    <goal>build</goal>
                                </goals>
                                <phase>package</phase>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>
    
  2. mvn package -Pnative を実行して、./target フォルダにネイティブ イメージを生成します。

  3. 実行可能ファイルを実行するのと同じようにアプリケーションを実行します。たとえば、./target/$IMAGE_NAME のようにします。プラグインはデフォルトでプロジェクトのアーティファクト ID に設定されます。

Gradle のセットアップ手順

  1. build.gradle ファイルに次のテキストを貼り付けて、アプリのメインクラスを設定します。

    application {
        mainClass.set('$MAIN_CLASS')
    }
    
  2. プラグインを追加するの説明に沿って、native-gradle プラグインを追加します。

  3. ./gradlew nativeCompile を呼び出して、ネイティブ イメージを ./build/native/nativeCompile ディレクトリにビルドします。

  4. アプリケーションを実行可能ファイルとして実行します。たとえば、./build/native/nativeCompile/$PROJECT_NAME とします。このプラグインを使用すると、イメージ名はデフォルトでプロジェクト名になります。

一般的な問題

SLF4J の互換性

SLF4J 依存関係を持つクライアント ライブラリでネイティブ イメージ コンパイルを実行すると、次のビルド時エラーが表示されることがあります。

Fatal error: com.oracle.graal.pointsto.util.AnalysisError$ParsingError: Error encountered while parsing io.grpc.netty.shaded.io.netty.util.internal.SystemPropertyUtil.getBoolean(java.lang.String, boolean)
Parsing context:
   at io.grpc.netty.shaded.io.netty.util.internal.SystemPropertyUtil.getBoolean(SystemPropertyUtil.java:96)
   at io.grpc.netty.shaded.io.netty.channel.epoll.Epoll.<clinit>(Epoll.java:33)
   at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.util.AnalysisError.parsingError(AnalysisError.java:153)
...
java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)
Caused by: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: No instances of org.slf4j.jul.JDK14LoggerAdapter are allowed in the image heap as this class should be initialized at image runtime. To see how this object got instantiated use --trace-object-instantiation=org.slf4j.jul.JDK14LoggerAdapter.

この問題を解決するには、META-INF/native-image/$GROUP_ID/$ARTIFACT_ID/native-image.properties ファイルに --initialize-at-run-time=io.grpc.netty.shaded.io.netty を追加します。

ただし、この構成では、アプリケーションがたどるコードパスによっては、生成されたネイティブ イメージのパフォーマンス コストが発生する可能性があります。

代わりに、Flogger や java.util.logging ライブラリなどの別のロギング ライブラリを使用することを検討してください。

質問

Java ネイティブ イメージのコンパイルに関する問題や質問は、GitHub の問題ページからご報告ください。

次のステップ