译自Configure Native Image with the Tracing Agent graal官方文档 , 以下所有命令需要在linux环境下操作,graalvm也支持windows。

要为使用 Java 反射、动态代理对象、JNI 或类路径资源的 Java 应用程序构建本机可执行文件,应为 native-image 工具提供 JSON 格式的配置文件或在代码中预先计算元数据。

您可以手动创建配置文件,但更方便的方法是使用跟踪代理(即Tracing agent,下面用代理一词代称)生成配置。本指南演示如何使用代理进行配置 native-image 。当您在 JVM 上运行应用程序时,代理会自动为您生成配置。

若要了解如何使用代码中预先计算的元数据生成本机可执行文件,请参阅文档 - Reachability Metadata 可访问性元数据

本指南中的示例应用程序使用 Java 反射。该 native-image 工具仅部分检测使用 Java 反射 API 访问的应用程序元素。因此,您需要向它提供有关反射访问的类、方法和字段的详细信息。

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

  1. 确保您已安装 GraalVM JDK,下载地址如下:https://www.oracle.com/java/technologies/downloads/ 选择graalvm的版本即可
  2. 将以下源代码保存在名为 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 应用程序使用命令行参数来确定要执行的反射操作。

  3. 运行如下命令:
    $JAVA_HOME/bin/javac ReflectionExample.java   # 编译
    $JAVA_HOME/bin/java ReflectionExample StringReverser reverse "hello" # 输出 olleh
    $JAVA_HOME/bin/java ReflectionExample StringCapitalizer capitalize "hello" # 输出 HELLO
  4. 使用 native-image 命令创建本机可执行文件,如下所示:
     $JAVA_HOME/bin/native-image --no-fallback ReflectionExample
  5. 使用以下命令运行生成的本机可执行文件:
    ./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)

    这表明,根据静态分析,native-image 工具无法确定 StringReverser 类是否被使用,所以未将其包含在本机可执行文件中。

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

以下步骤演示如何使用代理及其输出来创建依赖于反射且需要配置的本机可执行文件。

  1. 在工作目录中创建名为 META-INF/native-image 的目录:

    mkdir -p META-INF/native-image
  2. 在启用代理的情况下运行应用程序生成json配置,如下所示:

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

    此命令创建一个名为 reflect-config.json 的文件,其中包含类 StringReverser 的名称及其 reverse() 方法。

     [
    {
    "name":"StringReverser",
    "methods":[{"name":"reverse","parameterTypes":["java.lang.String"] }]
    }
    ]
  3. 构建本机可执行文件:

    $JAVA_HOME/bin/native-image ReflectionExample

    native-image 工具会自动使用 META-INF/native-image 目录中的配置文件。但是,建议将 META-INF/native-image 目录放到类路径上,可以通过 JAR 文件或使用标志 -cp 。(这样可以避免 IDE 用户在目录结构由 IDE 本身定义时出现混淆。)

  4. 测试可执行文件

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

    执行后会看到一个异常,类似于:

     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 的引用。

  5. 更新配置以包含类 StringCapitalizer 。您可以使用以下 config-merge-dir 选项手动编辑 reflect-config.json 文件或重新运行跟踪代理以更新现有配置文件,如下所示:

     $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"] }]
    }
    ]
  6. 重新生成本机可执行文件并运行,不会有报错了。

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

总结

graalvm让native镜像支持反射的关键是利用json提前告诉它哪些类的哪些方法会被反射调用,然后它就能力在运行时支持反射了。

如何使用graalvm为带有反射功能的java代码生成native image的更多相关文章

  1. ajax中网页传输(一)TEXT——带有删除功能的数据库表格显示练习

    网页之间传输的三种方式:TEXT.JSON.XML. 本章将讲解带有TEXT形势的ajax网页传输 第一:body部分代码 <title>ajax中TEXT讲解并且带有删除功能的表格< ...

  2. 一种实现C++反射功能的想法(一)

    Java的反射机制很酷, 只需知道类的名字就能够加载调用. 这个功能很实用, 想象一下, 用户只需指定类的名称, 就可以动态绑定类型, 而且只需通过字符串指定, 字符串的使用可以使得用户的修改只需修改 ...

  3. 使用反射功能在Unity运行状态通过Inspector面板修改字段和调用方法

    使用反射功能在Unity运行状态通过Inspector面板修改字段和调用方法 效果展示 一个很简单的组件脚本 运行状态在Inspector面板可以随便修改字段和调用方法 方法调用日志 设计由来 最近在 ...

  4. 功能:Java注解的介绍和反射使用

    功能:Java注解的介绍和反射使用 一.注解 1.注解介绍 java注解(Annotation),又称为java标注,是jdk5.0引入的一种机制. Java 语言中的类.方法.变量.参数和包等都可以 ...

  5. 进阶Java编程(10)反射与简单Java类

    1,传统属性自动赋值弊端 简单Java类主要由属性构成,并且提供有setter与getter类,同时简单Java类最大的特征就是通过对象保存相应的类属性的内容.但是如果使用传统的简单Java类开发,那 ...

  6. java反射(四)--反射与简单java类

    一.传统简单java类 简单的java类主要是由属性所组成,并且提供有相应的setter以及getter的处理方法,同时简单java类最大的特征就是通过对象保存相应的类的属性内容,但是如果使用传统的简 ...

  7. java jdbc ResultSet结果通过java反射赋值给java对象

    在不整合框架的情况下,使用jdbc从数据库读取数据时都得一个个的get和set,不仅累代码还显得不简洁,所以利用java的反射机制写了一个工具类,这样用jdbc从数据库拿数据的时候就不用那么麻烦了. ...

  8. MyCP -tx -xt 功能的Java实现

    MyCP -tx -xt 功能的Java实现 功能简介 java MyCP -tx XXX1.txt XXX2.bin 用来把文本文件(内容为十进制数字)转化为二进制文件 java MyCP -xt ...

  9. 软件工程作业 - 实现WC功能(java)

    项目地址:https://github.com/yogurt1998/WordCount 要求 基本要求 -c 统计文件字符数(实现) -w 统计文件单词数(实现) -l 统计文件行数(实现) 扩展功 ...

  10. DrawerLayout带有侧滑功能的布局类(1)

    DrawerLayout: DrawerLayout顾名思义就是一个管理布局的.使用方式可以与其它的布局类类似. DrawerLayout带有滑动的功能.只要按照drawerLayout的规定布局方式 ...

随机推荐

  1. wxpython窗体之间传递参数

    如何界面存在frame1与frame2,通过frame1打开页面frame2,并将frame2的值传递给frame1 可以使用回调函数传值参考具体代码如下: # -*- coding: utf-8 - ...

  2. Introduction to DFT

    服务器使用 登陆服务器:输入账号密码 打开terminal,保证至少一个terminal窗口是打开的 取消Linux操作系统的屏幕保护 设置Linux EDA工具配置 // 自定义环境变量设置 gvi ...

  3. 【Hash】字符串哈希

    Hash 的核心思想在于,将输入映射到一个值域较小.可以方便比较的范围,典型的用法就是将资源紧张的设备中的不定长字符串转化为定长整数,以达到节省空间的目的 如:printf("This is ...

  4. CSS - 正确解决 float 高度坍塌的问题

    <!DOCTYPE html> <html lang="en" dir="ltr"> <head> <meta cha ...

  5. 用CI/CD工具Vela部署Elasticsearch + C# 如何使用

    Vela 除了可以帮我们编译.部署程序,利用它的docker部署功能,也能用来部署其他线上的docker镜像,例如部署RabbitMQ.PostgreSql.Elasticsearch等等,便于集中管 ...

  6. Linux-文件权限-rwx-chmod

  7. [转帖]《Linux性能优化实战》笔记(四)—— CPU 使用率

    一. 节拍率与CPU时间 前一篇说到,Linux 作为一个多任务操作系统,将每个 CPU 的时间划分为很短的时间片,再通过调度器轮流分配给各个任务使用,因此造成多任务同时运行的错觉. 为了维护 CPU ...

  8. 关于信创CPU测试的一些想法和思路

    关于信创CPU测试的一些想法和思路 背景 最近荷兰政府颁布了关于半导体设备出口管制的最新条例. 好像45nm以下的工艺的设备都可能收到限制. 对中国的相关厂商比如长鑫还有华虹的影响应该都比较大. 认为 ...

  9. 【转帖】【漏洞提示】MySQL8.0.29因重大bug官网已下架

    前阵子,MySQL官网已经将 MySQL 8.0.29版本下架.据悉下架原因是由于MySQL 8.0.29 存在关于InnoDB解释器的重大Bug.而最新版本 8.0.30及以上的版本已修复此漏洞.各 ...

  10. [转帖]Guanaco, Llama, Vicuña, Alpaca该怎么区别

    https://zhuanlan.zhihu.com/p/106262896 在智利和秘鲁高原区经常会遇到的一种动物让人十分挠头,学术点称呼就是骆驼科其中一个族群--羊驼属和骆马属.头疼在于,分不清楚 ...