原生映像

Native Image 是一種將 Java 程式碼預先編譯為二進位檔的技術,也就是原生可執行檔。原生可執行檔僅包含執行階段所需的程式碼,即應用程式類別、標準程式庫類別、語言執行階段,以及來自 JDK 的靜態連結原生程式碼。

Native Image 產生的可執行檔具有幾個重要的優點,因為它

  • 使用 Java 虛擬機器所需資源的一小部分,因此執行成本較低
  • 在毫秒內啟動
  • 立即提供最高效能,無需預熱
  • 可以封裝到輕量級容器映像中,以實現快速高效的部署
  • 減少了攻擊面

原生可執行檔是由 Native Image 建置器native-image 建立的,它會處理您的應用程式類別和其他中繼資料,以建立特定作業系統和架構的二進位檔。首先,native-image 工具會對您的程式碼執行靜態分析,以判斷您的應用程式執行時哪些類別和方法是可到達的。其次,它會將類別、方法和資源編譯為二進位檔。整個過程稱為建置時間,以清楚區分 Java 原始程式碼到位元組碼的編譯。

native-image 工具可用於建置原生可執行檔 (預設值),或原生共用程式庫。本快速入門指南著重於建置原生可執行檔;若要深入瞭解原生共用程式庫,請前往這裡

為了熟悉 Native Image 的術語並更好地瞭解這項技術,建議您閱讀Native Image 的基礎知識

目錄 #

先決條件 #

native-image 工具 (可在 GraalVM 安裝的 bin 目錄中找到) 依賴於本機工具鏈 (C 程式庫的標頭檔、glibc-develzlibgcc 和/或 libstdc++-static)。可以使用您電腦上的套件管理員來安裝這些相依性 (如果尚未安裝)。選擇您的作業系統以尋找符合先決條件的指示。

Linux

在 Oracle Linux 上使用 yum 套件管理員

sudo yum install gcc glibc-devel zlib-devel

某些 Linux 發行版可能還需要 libstdc++-static。如果已啟用選用存放庫 (Oracle Linux 7 上的 ol7_optional_latest、Oracle Linux 8 上的 ol8_codeready_builder 和 Oracle Linux 9 上的 ol9_codeready_builder),則可以安裝 libstdc++-static

在 Ubuntu Linux 上使用 apt-get 套件管理員

sudo apt-get install build-essential zlib1g-dev

在其他 Linux 發行版上使用 dnf 套件管理員

sudo dnf install gcc glibc-devel zlib-devel libstdc++-static

MacOS

在 macOS 上使用 xcode

xcode-select --install

Windows

若要在 Windows 上使用 Native Image,請安裝Visual Studio 2022 17.6.0 版或更新版本,以及 Microsoft Visual C++ (MSVC)。有兩個安裝選項

  • 安裝具有 Windows 11 SDK (或更新版本) 的 Visual Studio Build Tools
  • 安裝具有 Windows 11 SDK (或更新版本) 的 Visual Studio

Native Image 在 PowerShell 或命令提示字元中執行,並且在它可以找到適當的 Visual Studio 安裝時,會自動在 Windows 上設定組建環境。

如需詳細資訊,請參閱在 Windows 上使用 GraalVM 和 Native Image

使用 Maven 或 Gradle 建置原生可執行檔 #

我們提供 Native Image 的 Maven 和 Gradle 外掛程式,以自動化建置、測試和設定原生可執行檔。

Maven #

Native Image 的 Maven 外掛程式新增了使用 Apache Maven 將 Java 應用程式編譯為原生可執行檔的支援。

  1. 在您喜愛的 IDE 中或從終端機建立名為「helloworld」的新 Maven Java 專案,其結構如下
     ├── pom.xml
     └── src
         ├── main
         │   └── java
         │       └── com
         │           └── example
         │               └── App.java
    

    例如,您可以執行此命令以使用快速入門原型建立新的 Maven 專案

     mvn archetype:generate -DgroupId=com.example -DartifactId=helloworld -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
    
  2. 將用於將專案編譯和組裝成可執行 JAR 檔案的一般 Maven 外掛程式新增至您的 pom.xml 檔案
     <build>
         <plugins>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-compiler-plugin</artifactId>
                 <version>3.12.1</version>
                 <configuration>
                     <fork>true</fork>
                 </configuration>
             </plugin>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-jar-plugin</artifactId>
                 <version>3.3.0</version>
                 <configuration>
                     <archive>
                         <manifest>
                             <mainClass>com.example.App</mainClass>
                             <addClasspath>true</addClasspath>
                         </manifest>
                     </archive>
                 </configuration>
             </plugin>
         </plugins>
     </build>
    
  3. 將以下設定檔新增至 pom.xml,以啟用 Native Image 的 Maven 外掛程式
     <profiles>
       <profile>
         <id>native</id>
         <build>
           <plugins>
             <plugin>
               <groupId>org.graalvm.buildtools</groupId>
               <artifactId>native-maven-plugin</artifactId>
               <version>${native.maven.plugin.version}</version>
               <extensions>true</extensions>
               <executions>
                 <execution>
                 <id>build-native</id>
                   <goals>
                     <goal>compile-no-fork</goal>
                   </goals>
                   <phase>package</phase>
                 </execution>
                 <execution>
                 <id>test-native</id>
                   <goals>
                     <goal>test</goal>
                   </goals>
                   <phase>test</phase>
                 </execution>
               </executions>
             </plugin>
           </plugins>
         </build>
       </profile>
     </profiles>
    

    version 屬性設定為最新的外掛程式版本 (例如,透過在 <properties> 元素中指定版本 <native.maven.plugin.version>)。

  4. 一步編譯專案並建置原生可執行檔
     mvn -Pnative package
    

    名為 helloworld 的原生可執行檔會在專案的 target/ 目錄中建立。

  5. 執行可執行檔
     ./target/helloworld 
    

    就是這樣,您已使用 Maven 成功為 Java 應用程式建立原生可執行檔。

用於 Native Image 建置的 Maven 外掛程式提供許多其他功能,這些功能對於具有更高複雜性的應用程式可能需要,例如資源自動偵測、產生所需的組態、在原生可執行檔上執行 JUnit 平台測試等等,詳見外掛程式參考文件

Gradle #

Native Image 的 Gradle 外掛程式新增了使用 Gradle 建置工具 將 Java 應用程式編譯為原生可執行檔的支援。

  1. 在您喜愛的 IDE 中或從終端機建立名為「helloworld」的新 Gradle Java 專案,其結構如下
     ├── app
     │   ├── build.gradle
     │   └── src
     │       ├── main
     │       │   ├── java
     │       │   │   └── org
     │       │   │       └── example
     │       │   │           └── App.java
     │       │   └── resources
    

    例如,使用 java 外掛程式初始化新的 Gradle 專案

    • 建立新的目錄並進入該目錄
        mkdir helloworld && cd helloworld
      
    • 產生專案
        gradle init --project-name helloworld --type java-application --test-framework junit-jupiter --dsl groovy
      

      按照提示操作。此命令會使用必要的目錄結構和建置檔案來設定新的 Java 應用程式。

  2. 透過將以下內容新增至專案 build.gradle 檔案的 plugins 區段,以啟用 Native Image 的 Gradle 外掛程式
     plugins {
     // ...
     id 'org.graalvm.buildtools.native' version 'x.x.x'
     }
    

    'x.x.x' 版本值指定最新的外掛程式版本。

  3. 執行 ./gradlew nativeCompile 以建置原生可執行檔
     ./gradlew nativeCompile
    

    名為 app 的原生可執行檔會在專案的 app/build/native/nativeCompile/ 目錄中建立。

  4. 執行原生可執行檔
     ./app/build/native/nativeCompile/app 
    

    就是這樣,您已使用 Gradle 成功為 Java 應用程式建立原生可執行檔。

用於 Native Image 建置的 Gradle 外掛程式具有許多其他功能,這些功能對於具有更高複雜性的應用程式可能需要,例如資源自動偵測、產生所需的組態、在原生可執行檔上執行 JUnit 平台測試等等,詳見外掛程式參考文件

使用 native-image 工具建置原生可執行檔 #

native-image 工具採用 Java 位元組碼作為其輸入。您可以從類別檔案、JAR 檔案或模組 (使用 Java 9 和更高版本) 建置原生可執行檔。

從類別 #

若要從目前工作目錄中的 Java 類別檔案建置原生可執行檔,請使用以下命令

native-image [options] class [imagename] [options]

例如,為 HelloWorld 應用程式建置原生可執行檔。

  1. 將此程式碼儲存到名為 HelloWorld.java 的檔案中
     public class HelloWorld {
         public static void main(String[] args) {
             System.out.println("Hello, Native World!");
         }
     }
    
  2. 編譯它並從 Java 類別建置原生可執行檔
     javac HelloWorld.java
     native-image HelloWorld
    

    它將在目前工作目錄中建立原生可執行檔 helloworld

  3. 執行應用程式

     ./helloworld
    

    您可以計時以查看使用的資源

     time -f 'Elapsed Time: %e s Max RSS: %M KB' ./helloworld
     # Hello, Native World!
     # Elapsed Time: 0.00 s Max RSS: 7620 KB
    

從 JAR 檔案 #

若要從目前工作目錄中的 JAR 檔案建置原生可執行檔,請使用以下命令

native-image [options] -jar jarfile [imagename]

native-image 的預設行為與 java 命令一致,這表示您可以將 -jar-cp-m 選項傳遞給 Native Image 來建置,就像您通常使用 java 時一樣。例如,java -jar App.jar someArgument 會變成 native-image -jar App.jar./App someArgument

遵循本指南以從 JAR 檔案建置原生可執行檔。

從模組 #

您也可以將模組化的 Java 應用程式轉換為原生可執行檔。

從 Java 模組建置原生可執行檔的命令為

native-image [options] --module <module>[/<mainclass>] [options]

如需如何從模組化 Java 應用程式產生原生可執行檔的詳細資訊,請參閱將 HelloWorld Java 模組建置為原生可執行檔

組建配置 #

您可以將許多選項傳遞給 native-image 工具,以配置組建程序。執行 native-image --help 以查看完整清單。傳遞給 native-image 的選項會從左到右進行評估。

如需不同的組建調整和深入瞭解建置時間配置,請參閱Native Image 組建配置

Native Image 會在組建期間輸出進度和各種統計資料。若要深入瞭解輸出和不同的組建階段,請參閱組建輸出。若要深入瞭解原生可執行檔的內容,請參閱組建報告

Native Image 和協力廠商程式庫 #

對於使用外部程式庫的更複雜應用程式,您必須為 native-image 工具提供中繼資料。

使用 native-image 建置獨立二進位檔是在「封閉世界假設」下進行的。native-image 工具會執行分析,以查看您的應用程式中哪些類別、方法和欄位是可到達的,且必須包含在原生可執行檔中。此分析是靜態的:它不會執行您的應用程式。這表示您應用程式中所有在執行階段可以呼叫的位元組碼都必須在建置時間已知 (觀察和分析)。

此分析可以判斷動態類別載入的某些情況,但它無法總是詳盡地預測 Java 原生介面 (JNI)、Java 反射、動態 Proxy 物件或類別路徑資源的所有用法。為了處理 Java 的這些動態功能,您可以使用有關使用反射、Proxy 等的類別或要動態載入的類別的詳細資料來通知分析。若要達成此目的,您可以使用 JSON 格式的組態檔案或在程式碼中預先計算中繼資料來為 native-image 工具提供資訊。

若要深入了解中繼資料、提供方式以及支援的中繼資料類型,請參閱可達性中繼資料。若要為您的應用程式自動收集中繼資料,請參閱中繼資料自動收集

某些應用程式可能需要額外設定才能使用 Native Image 編譯。如需更多詳細資訊,請參閱Native Image 相容性指南

Native Image 也可以透過自訂 API 與原生語言進行互操作。使用此 API,您可以指定 Java 應用程式中的自訂原生進入點,並將其建置為原生共用程式庫。若要深入了解,請參閱與原生程式碼的互通性

延伸閱讀 #

本入門指南適用於剛接觸或使用 Native Image 經驗較少的用戶。我們強烈建議這些用戶查看Native Image 基礎知識頁面,以便在深入研究之前更好地了解一些關鍵面向。

查看使用者指南,以獲取更多 Native Image 使用經驗、尋找示範範例,並了解潛在的使用情境。

為了逐步學習,請查看 Native Image 建置概述建置配置文件。

考慮執行互動式工作坊以獲得一些實務經驗:前往Luna Labs並搜尋「Native Image」。

如果您發現潛在的錯誤,請在GitHub 中提交問題

如果您想為 Native Image 做出貢獻,請遵循我們的標準貢獻工作流程

與我們聯繫