欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用graalvm為帶有反射功能的java代碼生成native?image的示例詳解

 更新時間:2024年02月09日 09:16:35   作者:心與夢  
graalvm讓native鏡像支持反射的關鍵是利用json提前告訴它哪些類的哪些方法會被反射調(diào)用,然后它就能力在運行時支持反射了,這篇文章主要介紹了如何使用graalvm為帶有反射功能的java代碼生成native?image,需要的朋友可以參考下

譯自Configure Native Image with the Tracing Agent graal官方文檔 , 以下所有命令需要在linux環(huán)境下操作,graalvm也支持windows。

要為使用 Java 反射、動態(tài)代理對象、JNI 或類路徑資源的 Java 應用程序構建本機可執(zhí)行文件,應為 native-image 工具提供 JSON 格式的配置文件或在代碼中預先計算元數(shù)據(jù)。

您可以手動創(chuàng)建配置文件,但更方便的方法是使用跟蹤代理(即Tracing agent,下面用代理一詞代稱)生成配置。本指南演示如何使用代理進行配置 native-image 。當您在 JVM 上運行應用程序時,代理會自動為您生成配置。

若要了解如何使用代碼中預先計算的元數(shù)據(jù)生成本機可執(zhí)行文件,請參閱文檔 - Reachability Metadata 可訪問性元數(shù)據(jù)

本指南中的示例應用程序使用 Java 反射。該 native-image 工具僅部分檢測使用 Java 反射 API 訪問的應用程序元素。因此,您需要向它提供有關反射訪問的類、方法和字段的詳細信息。

不配置Json格式的反射信息示例

將以下源代碼保存在名為 ReflectionExample.java 的文件中:

 import java.lang.reflect.Method;
 class StringReverser {
     static String reverse(String input) {
         return new StringBuilder(input).reverse().toString();
     }
 }
 class StringCapitalizer {
     static String capitalize(String input) {
         return input.toUpperCase();
     }
 }
 public class ReflectionExample {
     public static void main(String[] args) throws ReflectiveOperationException {
         if (args.length == 0) {
             System.err.println("You must provide the name of a class, the name of its method and input for the method");
             return;
         }
         String className = args[0];
         String methodName = args[1];
         String input = args[2];
         Class<?> clazz = Class.forName(className);
         Method method = clazz.getDeclaredMethod(methodName, String.class);
         Object result = method.invoke(null, input);
         System.out.println(result);
     }
 }

該Java 應用程序使用命令行參數(shù)來確定要執(zhí)行的反射操作。

運行如下命令:

$JAVA_HOME/bin/javac ReflectionExample.java   # 編譯
$JAVA_HOME/bin/java ReflectionExample StringReverser reverse "hello"   # 輸出 olleh
$JAVA_HOME/bin/java ReflectionExample StringCapitalizer capitalize "hello"   # 輸出 HELLO

使用 native-image 命令創(chuàng)建本機可執(zhí)行文件,如下所示:

 $JAVA_HOME/bin/native-image --no-fallback ReflectionExample

使用以下命令運行生成的本機可執(zhí)行文件:

./reflectionexample StringReverser reverse "hello"

您將看到一個異常,類似于:

 Exception in thread "main" java.lang.ClassNotFoundException: StringReverser
 at java.lang.Class.forName(DynamicHub.java:1338)
 at java.lang.Class.forName(DynamicHub.java:1313)
 at ReflectionExample.main(ReflectionExample.java:25)

這表明,根據(jù)靜態(tài)分析,native-image 工具無法確定 StringReverser 類是否被使用,所以未將其包含在本機可執(zhí)行文件中。

配置Json格式的反射信息示例

以下步驟演示如何使用代理及其輸出來創(chuàng)建依賴于反射且需要配置的本機可執(zhí)行文件。

在工作目錄中創(chuàng)建名為 META-INF/native-image 的目錄:

mkdir -p META-INF/native-image

在啟用代理的情況下運行應用程序生成json配置,如下所示:

$JAVA_HOME/bin/java -agentlib:native-image-agent=config-output-dir=META-INF/native-image ReflectionExample StringReverser reverse "hello"

此命令創(chuàng)建一個名為 reflect-config.json 的文件,其中包含類 StringReverser 的名稱及其 reverse() 方法。

 [
 {
 "name":"StringReverser",
 "methods":[{"name":"reverse","parameterTypes":["java.lang.String"] }]
 }
]

構建本機可執(zhí)行文件:

$JAVA_HOME/bin/native-image ReflectionExample

native-image 工具會自動使用 META-INF/native-image 目錄中的配置文件。但是,建議將 META-INF/native-image 目錄放到類路徑上,可以通過 JAR 文件或使用標志 -cp 。(這樣可以避免 IDE 用戶在目錄結構由 IDE 本身定義時出現(xiàn)混淆。)

測試可執(zhí)行文件

./reflectionexample StringReverser reverse "hello" # 輸出 olleh
./reflectionexample StringCapitalizer capitalize "hello"

執(zhí)行后會看到一個異常,類似于:

 Exception in thread "main" java.lang.ClassNotFoundException: StringCapitalizer
 at java.lang.Class.forName(DynamicHub.java:1338)
 at java.lang.Class.forName(DynamicHub.java:1313)
 at ReflectionExample.main(ReflectionExample.java:25)

跟蹤代理和 native-image 工具都無法確保配置文件完整。當您運行程序時,代理會觀察并記錄使用反射訪問了哪些程序元素。在這種情況下,該 native-image 工具尚未配置為包含對類 StringCapitalizer 的引用。

更新配置以包含類 StringCapitalizer 。您可以使用以下 config-merge-dir 選項手動編輯 reflect-config.json 文件或重新運行跟蹤代理以更新現(xiàn)有配置文件,如下所示:

 $JAVA_HOME/bin/java -agentlib:native-image-agent=config-merge-dir=META-INF/native-image ReflectionExample StringCapitalizer capitalize "hello"

此命令更新 reflect-config.json 文件,以包含類 StringCapitalizer 的名稱及其 capitalize() 方法。

 [
     {
     "name":"StringCapitalizer",
     "methods":[{"name":"capitalize","parameterTypes":["java.lang.String"] }]
     },
     {
     "name":"StringReverser",
     "methods":[{"name":"reverse","parameterTypes":["java.lang.String"] }]
     }
 ]

重新生成本機可執(zhí)行文件并運行,不會有報錯了。

 $JAVA_HOME/bin/native-image ReflectionExample
 ./reflectionexample StringCapitalizer capitalize "hello"

總結

graalvm讓native鏡像支持反射的關鍵是利用json提前告訴它哪些類的哪些方法會被反射調(diào)用,然后它就能力在運行時支持反射了。

到此這篇關于如何使用graalvm為帶有反射功能的java代碼生成native image的文章就介紹到這了,更多相關graalvm 生成native image內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論