如何使用graalvm为带有反射功能的java代码生成native image

译自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: StringReverserat 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: StringCapitalizerat 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提前告诉它哪些类的哪些方法会被反射调用,然后它就能力在运行时支持反射了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/594772.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python 自学(三) 之序列的应用

目录 1. 序列的含义 2. 序列的索引 P80 3. 序列相加 P81 4. 序列乘法 P82 5. in 关键字 P83 6. 计算序列的最大值max()&#xff0c;最小值min()和长度len() P83 7. 列表的初始化 list() P85 8. 列表元素的添加&#xff0c;…

apache httpd多后缀解析漏洞复现

一、漏洞描述 Apache Httpd支持一个文件拥有多个后缀,不同的后缀执行不同的命令,也就是说当我们上传的文件中只要后缀名含有php,该文件就可以被解析成php文件,利用Apache httpd这个特性,就可以绕过上传文件的白名单。 该漏洞和apache版本和php版本无关,属于用户配置不当造成的解…

如果一个n位正整数等于其各位数字的n次方之和

❤ 厾罗 如果一个n位正整数等于其各位数字的n次方之和 如果一个n位正整数等于其各位数字的n次方之和,则称该数为阿姆斯特朗数。 例如1^3 5^3 3^3 153。 1000以内的阿姆斯特朗数&#xff1a; 1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407。 以下代码用于检测用户输…

vc2017编译从github网站上下载的源码

以ZLmediakit为例 1.下载软件 cmakehttps://github.com/Kitware/CMake/releases/download/v3.20.5/cmake-3.20.5-windows-x86_64.zip Microsoft Visual Studio https://my.visualstudio.com/Downloads?qvisual%20studio%202017&wt.mc_ido~msft~vscom~older-downloads …

Unity DOTS中的baking(二)Baker的触发

Unity DOTS中的baking&#xff08;二&#xff09;Baker的触发 我们知道&#xff0c;当传入Baker的authoring component的值发生变化时&#xff0c;就会触发baking。不过在有些情况下&#xff0c;component所引用的对象没有变化&#xff0c;而是对象自身内部的一些属性发生了变化…

图形数据库

图形数据库是一种专门用于存储和查询图形数据结构的数据库系统。图形数据结构由节点&#xff08;顶点&#xff09;和边&#xff08;连接节点的关系&#xff09;组成&#xff0c;这种结构非常适合表示实体之间的复杂关系和网络。图形数据库的主要目标是提供高效的图形数据管理和…

C++上位软件通过LibModbus开源库和西门子S7-1200/S7-1500/S7-200 PLC进行ModbusTcp 和ModbusRTU 通信

前言 一直以来上位软件比如C等和西门子等其他品牌PLC之间的数据交换都是大家比较头疼的问题&#xff0c;尤其是C上位软件程序员。传统的方法一般有OPC、Socket 等&#xff0c;直到LibModbus 开源库出现后这种途径对程序袁来说又有了新的选择。 Modbus简介 Modbus特点 1 &#…

书生-浦路大模型全链路开源体系

2023年&#xff0c;大模型成为热门关键词 论文链接 大模型已经成为发展通用人工智能的重要途经 模型评测过程&#xff1a;从模型到应用 全链条开源开发体系 | 数据&#xff1a; 多模态融合 万卷包含文本、图像和视频等多模态数据&#xff0c;涵盖科技、文学、媒体、教育和法…

简单计算器实现,包括两个数

正在加载中... 简单计算器实现&#xff0c;包括两个数 ❤ 厾罗 简单计算器实现&#xff0c;包括两个数 以下代码用于实现简单计算器实现&#xff0c;包括两个数基本的加减乘除运算&#xff1a; 实例(Python 3.0) # Filename : test.py # author by : www.dida100.com …

SSD的控制器架构

SSD核心主要由3部分组成&#xff1a;主控&#xff0c;固件和闪存。 主控里面运行固件&#xff0c;固件对前后端数据进行处理并担负其他职能&#xff0c;包括磨损均衡&#xff0c;垃圾回收&#xff0c;内存映射&#xff0c;坏块管理等。 主控和固件就构成了SSD的控制器架构&am…

芯课堂 | MCU之EXT

概述 本文将介绍一下华芯微特MCU的嵌套向量中断控制器&#xff08;NVIC&#xff09;与外部中断/事件控制器&#xff08;EXTI&#xff09;的使用方法等。 01.嵌套向量中断控制器&#xff08;NVIC&#xff09; NVIC的全称是Nested vectoredinterrupt controller&#xff0c;即嵌…

普中STM32-PZ6806L开发板(HAL库函数实现-温度传感器DS18B20)

简介 主芯片STM32F103ZET6, 通过引脚PG11 连接DS18B20, 读取DS18B20采集的温度数据;电路原理图 DS18B20电路图 DS18B20 与 主芯片连接引脚 其他知识 DS18B20资料 DS18B20数据手册 DS18B20 简介 单线通讯的温度传感器, 测量温度在-55℃ 到 125℃&#xff0c; 在-10C 到…

平衡二叉树,力扣

目录 前序遍历与后续遍历 题目地址&#xff1a; 题目&#xff1a; 我们直接看题解吧&#xff1a; 审题目事例提示&#xff1a; 解题方法&#xff1a; 难度分析&#xff1a; 解题方法分析&#xff1a; 解题分析&#xff1a; 解题思路&#xff1a; 代码实现&#xff1a; 补充说明…

【每日论文阅读】生成模型篇

联邦多视图合成用于元宇宙 标题: Federated Multi-View Synthesizing for Metaverse 作者: Yiyu Guo; Zhijin Qin; Xiaoming Tao; Geoffrey Ye Li 摘要: 元宇宙有望提供沉浸式娱乐、教育和商务应用。然而&#xff0c;虚拟现实&#xff08;VR&#xff09;在无线网络上的传输是…

【UEFI基础】EDK网络框架(通用函数和数据)

通用函数和数据 DPC DPC全称Deferred Procedure Call。Deferred的意思是“延迟”&#xff0c;这个DPC的作用就是注册函数&#xff0c;然后在之后的某个时刻调用&#xff0c;所以确实是有“延迟”的意思。DPC在UEFI的实现中包括两个部分。一部分是库函数DxeDpcLib&#xff0c;…

Unity中使用四元数乘法表示旋转

四元数乘法旋转的本质是旋转的连续应用。当你执行p * q时&#xff0c;可以理解为首先应用四元数p的旋转&#xff0c;然后再应用四元数q的旋转。 四元数旋转乘法主要分为全局坐标的旋转和局部坐标的旋转. 全局坐标下的旋转&#xff1a; transform.rotationtransform.roation*…

考研复试英语口语问答举例第一弹

考研复试英语口语问答举例第一弹 文章目录 考研复试英语口语问答举例第一弹Question &#xff1a;介绍你的读研兴趣与动机Answer1&#xff1a;&#xff08;医疗与人工智能结合方向&#xff09;Answer2&#xff1a;&#xff08;分布式与网安方向&#xff09;Answer3&#xff1a;…

AUTOSAR规范与ECU软件开发(基础篇)1.2 汽车电子控制系统的基本构成

目录 前言 1、 传感器 2、 电子控制单元(ECU) 3、 执行器 前言 汽车电子控制系统主要由传感器(Sensor) 、 电子控制单元(Electronic Control Unit, ECU) 和执行器(Actuator) 组成(图1.1) ,对被控对象(Controlled Object) 进行控制。

斐波那契数列指的是这样一个数列 0, 1, 1, 2, 3,

斐波那契数列指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13,特别指出&#xff1a;第0项是0&#xff0c;第1项是第一个1。从第三项开始&#xff0c;每一项都等于前两项之和。 Python 实现斐波那契数列代码如下&#xff1a; 实例(Python 3.0) # -*- coding: UTF-8 -*- # File…

JS和TS的基础语法学习以及babel的基本使用

简介 本文主要介绍了一下js和ts的基础语法,为前端开发zuo JavaScript 更详细的 JavaScript 学习资料&#xff1a;https://developer.mozilla.org/zh-CN/docs/Web/JavaScript 简介 定位 : JavaScript 是一种动态语言&#xff0c;它包含类型、运算符、标准内置&#xff08; bu…