Java Code JVM

Graalvm反射配置辅助工具agentlib

Posted on 2021-03-30,3 min read
  • Graalvm通过静态分析提前编译来为Java应用程序构建高度优化的本机可执行文件,这就需要在编译时就知道所有的程序类型,而java中的反射、动态代理等功能,在编译时不确定具体的类型,所以在使用GraalVm构建native image前需要通过配置列出反射可见的所有类型。反射的配置是一个json格式的文件。为了简化这种反射的配置,GraalVm提供agentlib工具,来辅助生成这个配置文件。
  • 在使用agentlib生成配置时,建议将应用的测试用例全部跑一边,让应用覆盖到所有的业务接口,不然,生成的配置可能覆盖不到所有的反射类
  • 在执行期间,代理与Java VM交互以拦截所有查找类,方法,字段,资源或请求代理访问的调用。然后,代理生成的文件jni-config.json,reflect-config.json,proxy-config.json、resource-config.json在指定的目录输出。生成的文件是JSON格式的独立配置文件,其中包含所有拦截的动态访问。
  • Reflection配置文档:https://github.com/oracle/REFLECTION.md
  • agetnlib文档:https://www.graalvm.org/reference-manual/native-image/BuildConfiguration/#assisted-configuration-of-native-image-builds

一个简单的Demo

  • Demo路径:https://github.com/Gloduck/graalvm-demo
  • 一个读取文件的一个demo,读取类路径下的config.json并且输出。
package cn.gloduck;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.json.JSONUtil;

import java.io.IOException;

import java.io.InputStream;
import java.nio.charset.Charset;

/**
 * @author Gloduck
 */
public class NativeStarter {
    public static void main(String[] args) throws IOException {
        InputStream inputStream = NativeStarter.class.getResourceAsStream("config.json");
        String json = IoUtil.read(inputStream, Charset.defaultCharset());
        System.out.println(json);
    }
}

如图,直接编译是无法输出的。
直接编译
这时候可以通过agentlib工具来进行分析,首先先将jar包进行打包,然后运行分析工具。

java -agentlib:native-image-agent=config-output-dir=配置文件输出路径 -jar 分析的jar包

接着分析出来的文件会出现在配置的输出路径里,接着将这些文件全部复制到项目的resource/META-INF/native-image路径下。
然后重新运行打包,结果就能输出了。
使用工具后


下一篇: AQS源码分析→

loading...