从AOT编译的二进制文件中提取Java类信息

Java 世界中的提前(AOT)编译长期以来一直是争论的话题,但直到 GraalVM 出现之前,还没有任何工具可以实现良好的 AOT 编译,更不用说驱动整个生态系统了。尽管 GraalVM 提供了原生镜像工具来有效协助开发人员进行 AOT 编译,但由于 Java 生态系统的复杂性和多样性,尤其是反射和代理技术,实现 Java 应用程序开箱即用的 AOT 编译仍然非常具有挑战性。广泛应用于各种通用框架中。

Spring Native 项目

得益于 Spring Framework 团队的 Spring Native 项目,他们能够通过 Maven 或 Gradle 插件实现项目的一键 AOT 编译。但目前仅适用于 Spring Boot 项目。

请使用Sping Native生成AOT编译的Java程序

以下是官方的 Spring Native 示例,用于生成 AOT 编译的 Java 应用程序(测试环境:Ubuntu 20.04、Docker 20.10.6)

git clone https://github.com/spring-projects-experimental/spring-native.git
cd spring-native/sample/petclinic-jpa
./build.sh

经过相对较长的编译时间和大量的内存消耗后,我们可以在目标目录中获得AOT编译的Java程序。这是一个独立的二进制文件,可以独立运行,没有任何依赖。

img

petclinic-jpa是一个通过AOT编译的程序,可以直接运行

从AOT编译的二进制文件中提取Java类信息

Java代码保护在过去一直是一个非常棘手的问题,AOT也被认为是Java代码保护的一种解决方案。不幸的是,现在很多Java程序无法脱离框架。由于框架的复杂性,即使是AOT编译的程序也必须在最终生成的二进制文件中包含类信息。类文件实际上整齐地排列在二进制文件的资源区中。

以下工具可以从AOT编译的二进制文件中扫描和提取类信息

以下工具可以从AOT编译的二进制文件中扫描和提取类信息

https://github.com/3-keys/binary-classfile-reader

git clone https://github.com/3-keys/binary-classfile-reader
cd binary-classfile-reader
./gradlew run --args='<path-of-the-binary-file> <output-folder>'

以上一步得到的petclinic-jpa为例,从中提取出类信息,并与源码进行对比。可以看到型号信息、控制器信息、服务信息都可以获取到。

img