編譯原生圖片

使用 Java 適用的 Cloud 用戶端程式庫時,您可以將應用程式編譯為原生映像檔。這種做法會運用預先編譯功能,縮短應用程式的冷啟動時間和記憶體用量,進而提升應用程式效能。

用戶端程式庫版本

請確認您使用的是 25.4.0 以上版本的 Cloud 程式庫物料清單 (libraries-bom),或是 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. 安裝適當的 JDK 發行版本,例如 GraalVM

  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 問題頁面回報。

後續步驟